SurfaceFlinger.cpp revision 784421160727c434c2a2897ed3345445fcc30f75
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 2486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h> 25b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h> 26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 3867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h> 39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 45392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 51cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 57921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 58ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 640f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 65faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 66d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 67d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 73a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 78875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 89ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 90ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12499b49840d309727678b77403d6cc9f920111623fMathias Agopian 12599b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12699b49840d309727678b77403d6cc9f920111623fMathias Agopian 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 134875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 137a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 1384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 142a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 147ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 148faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 149948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 1509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mDaltonize(false), 1519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix(false) 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 153a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1578afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 158b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 15950210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 160b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1668afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 16763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 17063f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 172c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 173c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 18099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 183a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 185a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 188c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 18999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 19199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 19313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 196a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1997e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 20296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 20396f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 20496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 20596f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 211dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 2303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 2318dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 232dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2386c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 257692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2689e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 269e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 285a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2863330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 292921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 296a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 298a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 302921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 305921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 308921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 317faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 318faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3195167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3205167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const char* label) : 3210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mPhaseOffset(phaseOffset), 3230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3245167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncOnLabel(String8::format("VsyncOn-%s", label)), 3255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncEventLabel(String8::format("VSYNC-%s", label)), 3260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mDispSync(dispSync) {} 327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // Do NOT lock the mutex here so as to avoid any mutex ordering issues 332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // with locking it in the onDispSyncEvent callback. 333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3340a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis status_t err = mDispSync->addEventListener(mPhaseOffset, 335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3405167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3485167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3640a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 3650a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 3665167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 3670a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 3770a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const nsecs_t mPhaseOffset; 3780a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 3805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 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 422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> producer; 423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> consumer; 424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza 427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, 428b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza consumer); 42919e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall int32_t hwcId = allocateHwcDisplayId(type); 430f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 43119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall type, hwcId, mHwc->getFormat(hwcId), isSecure, token, 432b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza fbs, producer, 43305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 43886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGD("marking display %zu as acquired/unblanked", i); 4392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(HWC_POWER_MODE_NORMAL); 440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 442f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 444cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // make the GLContext current so that we can create textures when creating Layers 446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // (which may happens before we render something) 447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 448a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 449028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4515167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden vsyncPhaseOffsetNs, true, "app"); 452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mEventThread = new EventThread(vsyncSrc); 4530a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden sfVsyncPhaseOffsetNs, true, "sf"); 4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mSFEventThread = new EventThread(sfVsyncSrc); 4560a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mEventQueue.setEventThread(mSFEventThread); 457028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 460d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // set a fake vsync period if there is no HWComposer 462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mHwc->initCheck() != NO_ERROR) { 463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(16666667); 464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 465faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 46792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 47113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 472a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 473a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 4779e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ? 4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 4803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 486a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 496d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 4982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 5002adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder()); 5016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 503134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (configs == NULL) { 5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 510692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5119e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 512692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5151604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 520c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 5407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const Vector<HWComposer::DisplayConfig>& hwConfigs = 5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza getHwComposer().getConfigs(type); 5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza for (size_t c = 0; c < hwConfigs.size(); ++c) { 5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const HWComposer::DisplayConfig& hwConfig = hwConfigs[c]; 5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float xdpi = hwConfig.xdpi; 5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float ydpi = hwConfig.ydpi; 5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 5737f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.w = hwConfig.width; 5777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.h = hwConfig.height; 5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.fps = float(1e9 / hwConfig.refresh); 58191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 58291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden 58391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.presentationDeadline = 59691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->push_back(info); 6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 606dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 60767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnarstatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& display, 60867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 60967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 61067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 61167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 61267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 61367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 61467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 61567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 61667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 61767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 61867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 61967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 6206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 6216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return getDisplayDevice(display)->getActiveConfig(); 6227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 623dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 6256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 6266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 6276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 6286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 6296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 6416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 6426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 6436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 6456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 6496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 6547306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 6557306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 656784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 6579ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 6587306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 6597306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 6606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 6616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 6626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 6637306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 6646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 6656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 6666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 675888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 676c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 677c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 678d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 679d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 680d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 681d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 682d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 683d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 684d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 685d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 686d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 687d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 688d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 689d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 690d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 691d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 692d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 6938aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 694bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 695bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 70099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 715c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 720c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 72299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 72699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 7294f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 7304f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 7314f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 73299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 734faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 735faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 736948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 737faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 738d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 739d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 740faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 74143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 742faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 743faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 744948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 745faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 746faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 747948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 748948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 749948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 750948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall ALOGE("resyncToHardwareVsync called when HW vsync unavailable"); 751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 752948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 753948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 754faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const nsecs_t period = 755faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 756faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 757faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 758faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 759faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 760faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 762d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 763d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 764faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 766faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 767faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 768948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 769faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 770faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 771d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 772d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 773faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 774faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 775faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 776948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 777948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 778948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 779faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 780faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 781faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 782d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 783faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 784d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 785d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 786d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 787d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 788faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 789148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 790d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 791d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 792d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 793d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 794d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 795d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 796148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 797148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 798148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 799148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 800148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 801148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 802148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 803148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 804148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 805148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 8069e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8079e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 8089e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 809692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 810692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 8119e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 812692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 813692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 8149e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 8159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 8169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8179e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 8183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 8198630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 82181cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 822faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 82381cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 8248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8258630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 8264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 8271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 82899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 8299eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian case MessageQueue::TRANSACTION: 8309eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian handleMessageTransaction(); 8319eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian break; 8324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 8344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 8354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 8364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 8374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 8384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 8394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 8404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 84687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 8474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 85287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8543a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 856cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 857cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 858cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 863cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 865cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 867cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 870cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 8833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 8843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 8853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 887da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 892cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 897bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 898bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 899bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 900bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 901bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 902bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 903cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 905cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 907cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 910cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 915cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 916cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 917cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 918cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 919a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 920cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 9221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian layers[i]->onPostComposition(); 926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 9274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 928faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const HWComposer& hwc = getHwComposer(); 929faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 931faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 932faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 933faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 934faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 935948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 936faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 937faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 938faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 940faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 9412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 942faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 943faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 944faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 945faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 9474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 9484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 949a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 9504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 9514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 9524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 9534b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 9544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 9554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 9564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 9574b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 9584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 959cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 96352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 964cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 96587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 96687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 967ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 9681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 96992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 970ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 971ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Vector< sp<Layer> > layersSortedByZ; 9734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 9747e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 9757e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 9762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 9771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 978ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 9797e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 9801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 981ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 9821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 9831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 984ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 985a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 986a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 987a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 988a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 989ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 990ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 99187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 99287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 9933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 9957e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 9967e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 9977e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 9983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9993b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1000cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 10013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1002cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 1003028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1004b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1005b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1006b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1007b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1008b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1009b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1010b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1011b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1012b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1013b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1014b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1015b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1016b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1017b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1018b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1019b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1020b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1021b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1022b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1023b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1024b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 10257143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1026b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1027b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1028b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1029b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1030028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1031028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 103252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 103352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 103452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 1035a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 1036a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 1037a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1038a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 1039a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 1040a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1042a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 1043a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 1044a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 1045a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1046a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1047a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1049a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 10509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { 1051a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 1052a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1053a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1054a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1055a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1056a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1057a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1058a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1059a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 106092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 10614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 1062e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 1063e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 106413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1065cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 1066e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 1067a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1068a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1069a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1070a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 1071a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 1072a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 1073a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 107413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1075a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 10761e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 107752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 107887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1079a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 108003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // If possible, attempt to use the cursor overlay on each display. 108103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 108203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 108303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 108403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id >= 0) { 108503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 108603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 108703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 108803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 108903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 109003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 109103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 109203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer->isPotentialCursor()) { 109303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews cur->setIsCursorLayerHint(); 109403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 109503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 109603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 109703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 109803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 109903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 110052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 110152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 110238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 110338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 110438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall sp<const DisplayDevice> hw(mDisplays[dpy]); 110538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall hw->prepareFrame(hwc); 110638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 110752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 110952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1110cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1111cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 111252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 111392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 11152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1116cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1117cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 111802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 111902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 112002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 112102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1122cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1123cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 112587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 112652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 11274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 112952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1134841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1135b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1136a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1137a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1138c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 113952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 1140ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 11412a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 11422a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 11432a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 11442a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 1145875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11462a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 1147e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 114852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 114952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 11506da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // make the default display current because the VirtualDisplayDevice code cannot 11516da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // deal with dequeueBuffer() being called outside of the composition loop; however 11526da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // the code below can call glFlush() which is allowed (and does in some case) call 11536da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // dequeueBuffer(). 11546da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11556da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian 115692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1159da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 116052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 1161e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1162e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 11631e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 11641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 116552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1166d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 116952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1170d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 117152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1172ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1173e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1174e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1175a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1176a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 11776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 11786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 11796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 11806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 11816547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 118487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1186841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1187841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 11887cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 11897cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 11907cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 11917cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 11927cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 11937cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1194ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1195ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1196ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1197ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1198ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1199ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1200ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1201ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1202ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1203ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 120587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1206ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1207ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1208ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1209ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1210ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 12113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 121387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 12143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 12153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 12363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 124092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 124192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 124292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 124592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 124792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 124893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 124992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 125092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 125192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 125292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 125392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 125492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 125792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 12583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 125927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 126027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 126127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 126202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1263875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 126402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 126502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 126602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 12679e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 12687adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 126902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 127292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 127392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 127492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 12763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1277111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 127993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 128093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 128193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 128202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 128302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 128402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 128593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 128693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 128793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 128893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 128993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 129092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 129193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1292db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 129393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 129493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 129593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 129693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 129700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 129800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 129900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 130000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 130100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 13024fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 130393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 130447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 130547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 130647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 130792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 130892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 130992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 131092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 131192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 131292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 131392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1314e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1315e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1316cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 131799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1318db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1319b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1320b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 1321b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 1322b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 1323db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 132402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall int32_t hwcDisplayId = -1; 132599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 132602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 132702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 132802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 132999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1330db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 13311f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int width = 0; 13321f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int status = state.surface->query( 13331f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_WIDTH, &width); 13341f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 13351f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query width (%d)", status); 13361f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int height = 0; 13371f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza status = state.surface->query( 13381f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_HEIGHT, &height); 13391f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 13401f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query height (%d)", status); 13411f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 || 13421f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza (width <= MAX_VIRTUAL_DISPLAY_DIMENSION && 13431f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) { 13441f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza hwcDisplayId = allocateHwcDisplayId(state.type); 13451f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza } 13461f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza 1347db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface( 1348b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *mHwc, hwcDisplayId, state.surface, 1349b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqProducer, bqConsumer, state.displayName); 1350db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1351db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 135247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 135399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 135499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1355cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1356cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1357cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1358cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 135902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1360cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1361cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1362b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza dispSurface = new FramebufferSurface(*mHwc, state.type, 1363b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqConsumer); 1364b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza producer = bqProducer; 1365cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1366cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1367cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 136899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1369cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 137019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall state.type, hwcDisplayId, 137119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall mHwc->getFormat(hwcDisplayId), state.isSecure, 137205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall display, dispSurface, producer, 137305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1374cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1375cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 13764fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 13778dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1378cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 13791c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (state.isVirtualDisplay()) { 13801c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (hwcDisplayId >= 0) { 13811c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall mHwc->setVirtualDisplayProperties(hwcDisplayId, 13821c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getWidth(), hw->getHeight(), 13831c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getFormat()); 13841c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 13851c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } else { 13867adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 13871c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 138893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 138992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 139092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 13958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 13968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 13978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 13988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 14008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 14018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 14038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 14048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 14058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 14078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 14088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 14108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 14118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 14128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 14138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 14158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 14168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 14178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 14188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 14198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 14211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 14228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 14238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 14248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 14258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 14268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 14278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 14288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 14308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 14318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 14328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 14338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 143491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 14358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 14368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 144091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 144191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 144291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 144391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 144491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 144591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 144691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 144791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 14488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 144991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 14508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 14538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 14543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 14553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 14563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 14591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 14603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 14613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 14633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 14643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 14653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 14663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 14673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 14683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 14703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 14711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 14723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 14733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 14743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 14753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 14763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 14771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 14781501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 14791501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 14801501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 14810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 148603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 148703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 148803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 148903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 149003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 149103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 149203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer& hwc(getHwComposer()); 149303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 149403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 149503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 149603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id < 0) { 149703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 149803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 149903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 150003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 150103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 150203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 150303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 150403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 150503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) { 150603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 150703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 150803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 150903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect cursorPos = layer->getPosition(hw); 151003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hwc.setCursorPositionAsync(id, cursorPos); 151103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 151203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 151303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 15144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 15154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 15164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 15174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 15184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 15194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 15204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 15214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 15224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 15244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 15264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 15274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 15284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 15294b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 15304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 15312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 15322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 15334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 153787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 153887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1540841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1541841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 154687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 155013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 15531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 155687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 155787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 155887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1559ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1560ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1561ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1563ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1564ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1565ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1566ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1567ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1568ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1569ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1571ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1575ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1577ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1578a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1579a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1580a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1581a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1582a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1583a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1584a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1585a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1586a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1587a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1590da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 15914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 15925219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian Rect bounds(s.transform.transform(layer->computeBounds())); 1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 15974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 15984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 15994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 16004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 16012ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = tr.transform(s.activeTransparentRegion); 16024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 16034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 16044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1605a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 16064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 16082ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = s.activeTransparentRegion; 16094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 16134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 16364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1639a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1650a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 16524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 16534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 166087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 16648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1665a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1668a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1669a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 167687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 167792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 16784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 16794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 16804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 168192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 168292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 168387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 168487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 168587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 168899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 16894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 16901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 169151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 169251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 169351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 169451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 169551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 169651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 169751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 169851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 169951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 170051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 170151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Vector<Layer*> layersWithQueuedFrames; 170251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layers.size(); i<count ; i++) { 17031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 170451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner if (layer->hasQueuedFrame()) 170551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner layersWithQueuedFrames.push_back(layer.get()); 170651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner } 170751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { 170851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Layer* layer = layersWithQueuedFrames[i]; 170987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 17101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 171187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 17124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 17134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 17143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1717ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1718ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1719ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1720ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1721ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 172299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 172487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17267143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 17277143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 17287143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 17297143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 17307143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 17317143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 17327143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 17337143316af216fa92c31a60d4407b707637382da1Dan Stoza } 17347143316af216fa92c31a60d4407b707637382da1Dan Stoza 173587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 173687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1737b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 17384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 17410f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 174229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 174329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 174429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 17454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 17470f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 174829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1749df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 175095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 17510f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 17524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 175429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 17554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 17564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { 17613f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if (!doComposeSurfaces(hw, dirtyRegion)) return; 1762ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 1763ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian RenderEngine& engine(getRenderEngine()); 17649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mat4 colorMatrix = mColorMatrix; 17659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDaltonize) { 17669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette colorMatrix = colorMatrix * mDaltonizer(); 17679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 17689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette engine.beginGroup(colorMatrix); 1769ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1770ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian engine.endGroup(); 1771ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 17744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1775da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1776da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1777da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17803f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 178385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 17848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 17851e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 17861e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1787a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1788d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall bool hasGlesComposition = hwc.hasGlesComposition(id); 178985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1790875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) { 1791c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1792c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 17933f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 17943f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 17953f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 17963f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 17973f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 1798c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1799a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1800a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 180185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1802e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1803b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1804b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1805b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 18063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 1807b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 18083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 0); 1809b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1810766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1811766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1812766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1813766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1814766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1815766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1816766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1817766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1818766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1819766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1820766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1821766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1822766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1823766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1824b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 182587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1826b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 182755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1828b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1829a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1830f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1831766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1832766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1833f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1834f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1835f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1836766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1837f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1838f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1839f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1840f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 18413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1842f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 18433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian const uint32_t height = hw->getHeight(); 18443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setScissor(scissor.left, height - scissor.bottom, 18453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 1846f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1847f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 184885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 18494b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 185085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 185185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 185285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 18534b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 185413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); 185585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 185685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 185785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 185885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 185985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 186013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 186285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 186385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 186403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews case HWC_CURSOR_OVERLAY: 186585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 1866ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 186785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 186885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 18694125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden && layer->isOpaque(state) && (state.alpha == 0xFF) 187085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 187585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 187685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 187785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 187985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1880a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1881da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1882da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1883da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 188486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i); 1885da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1886da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1887cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1888a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 188985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 189085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 189185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 189285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 189385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 189413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 189685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 189785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 189885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 189985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 19004b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 19014b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1902f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1903f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 19043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableScissor(); 19053f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 1906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 190955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 19103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 19113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1914ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client, 1915ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 19166710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 191713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 19181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 191996f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 1920ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 19214f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 192296f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1923921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1924921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 19256710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mGraphicBufferProducerList.add(gbc->asBinder()); 192696f0819f81293076e652792794a961543e6750d7Mathias Agopian} 192796f0819f81293076e652792794a961543e6750d7Mathias Agopian 19283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { 192996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 193013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 19326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mLayersPendingRemoval.push(layer); 1933076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 19346710604286401d4205c27235a252dd0e5008cc08Mathias Agopian setTransactionFlags(eTransactionNeeded); 1935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1940c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 1941dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1942dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1943dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 19443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 195199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19568b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 19578b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 19588b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 19598b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 19608b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 19617c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 1962698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 196328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 19652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 19662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 19672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 19682d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 19697c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 19702d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 19712d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 19727c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 19737c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 19747c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 19752d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 19762d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 19772d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19782d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19792d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19802d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 1981e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1982e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1984e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1985b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1986b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1988698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1989698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1990d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 1991d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 1992d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 1993d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 1994d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 1995d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 1996d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 1997d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 1998d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<IBinder> binder = s.client->asBinder(); 1999d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2000d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2001d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2002d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2003d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2004d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2005d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2006d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2007698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2008386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 200928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2010386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 201128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2012698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2013386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2014386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2015386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 20162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 20172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 20192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2020386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 20212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2022386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2023386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2024386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2025386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 20262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 20272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2028386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2029386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2030cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2034e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2035e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 20369a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 20379a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 20389a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 20399a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2040e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 20419a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 20423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2043e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2044e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2045e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 2046e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2047e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2048e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2049e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2050e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2051e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2054e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2055e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 205600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2057e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2059e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2060e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2061e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2062e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2063e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2064e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2065e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2066e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2067e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2068e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2069e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 207047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 207147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 207247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 207347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 207447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 207547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 207647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 207747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 207847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 207947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2080e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2081e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2082e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2084e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2085e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2086e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2087e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2088e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 208913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2090e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2091e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2092e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 2093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 2094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2095e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2096e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2099e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2104e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2105e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2107e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2108e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2110e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2111e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2112e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 2113e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 2114e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2115e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2116e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2117e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2118e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2119e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2120e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2121e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2122e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2123e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 21244125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if ((what & layer_state_t::eVisibilityChanged) || 21254125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden (what & layer_state_t::eOpacityChanged)) { 21264125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden // TODO: should we just use an eFlagsChanged for this? 2127e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2129e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 2131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 2132e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2133e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2134e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2135e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2136e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2137e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 2138e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2139e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2140e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2141e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2142e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2143e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2144e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2145e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2146e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2147e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2148e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 21494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 21500ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 21510ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 21524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 21534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 21566e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2157921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 21586e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 21594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 21606e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 21618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 21624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 21634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 21644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 21654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 21663165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 21673165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 21684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 21694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 21704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 21723165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 21734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 21744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 21754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 21764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 21774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 21784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (result == NO_ERROR) { 21836710604286401d4205c27235a252dd0e5008cc08Mathias Agopian addClientLayer(client, *handle, *gbp, layer); 218496f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 21864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 21904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 21914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 219492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 22008f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 22054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 22064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 22074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2208b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 22124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 22164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 22174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 22204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2221b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 22224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2223118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2224118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2225ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 22269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 22276710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 22286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 22296710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 22306710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 22316710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 22326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 22336710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 22349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 22359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 22369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 22379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 223813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 22416710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 2242ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 224313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> l(layer.promote()); 2244ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 22456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 2246e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2247ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2248ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2249ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2252b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2253b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 225413a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 225501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 225613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 225713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 225813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 225901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 226001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 226201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 226313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 22644c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 22654c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 226647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 226747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 226813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 226913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 22702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 22716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 22726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const nsecs_t period = 22736547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 22746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 227513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 227613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 227713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 227813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 227913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 228013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 228113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 228213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 228313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 228413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 228513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 228613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 228713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 228813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 228913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 229013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 22912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 22922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 22932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 22942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 22952c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 22962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 229713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 22982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 22992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2300c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2301c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2302c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 23042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 23052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 23062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 23072c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2308c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 23102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2311c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2312c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2313c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2314948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2315c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 23182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 23192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2320c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2321948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2322948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2323cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2324cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2325cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2326c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 23282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 23292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 23302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 23312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2332b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 23362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2337db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2338db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 23392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2340b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 23412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 23422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 23432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2344b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 23452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2346db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 23472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 23487306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 23499e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 23502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 23512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2352db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 23532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2354db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2355b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2356b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2357b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 23582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2359db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2360b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2361b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2362b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2363b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 236799b49840d309727678b77403d6cc9f920111623fMathias Agopian 2368bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2369bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2370bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2371bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2372bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 237374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2374bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 23769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 23779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 23789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 23799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 23809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 23819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 23829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 23839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 23849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 238574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append( 23869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 23879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 23889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 23899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 239082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 239225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 239325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 239425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 239525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 239625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 239774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 239835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 239925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 240025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 240125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 240225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 240382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 240474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 240535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 240682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 240725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 240825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 240925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 241025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 241174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 241235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 241325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2414c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2415c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2416c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2417c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2418c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2419c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2420c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 242474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 242648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 242948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 243182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 243282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 243382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 243448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2435c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2436c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 243725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 243825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 243925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 244025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 244113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 244274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 244325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 244425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 244525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 244682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 244774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 244882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 244982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 245082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 245182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 245282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 245382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 245448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 24554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const nsecs_t period = 24564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 245786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 24584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 24594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2460d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 24614b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 24624b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 24634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 24644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 246513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 24664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2467d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 24684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 246982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 247082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 247182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2472ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 247325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2474c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 247525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 247625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 247725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 247825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 247925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 248025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 248125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 248225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 248325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 248425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 248513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 248625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2487d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 248825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 248925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 24904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2491d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 249225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 249325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 24946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 24956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 24966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 24976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 24986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 24996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 25006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 25016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 25026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 25036547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 25046547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 25056547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 25066547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 25074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 25084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 25094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 25104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 25114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 25124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 25134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 25154803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 25164803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25174803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 25184803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 25194803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25204803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 25214803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 25224803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 25234803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 252474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 252574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 252682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 25273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 25283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 25293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 25303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 25313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 25323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 25333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 25343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 25353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 253682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 253782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 253882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 253982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 254082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 254182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2542bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 254382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 25444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 25454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 25463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 25473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 25484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 25493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 25514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 25524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 25534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 25544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 25553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2556ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 25573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2558ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2559ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2560ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 256141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 256241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 256341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 256424cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 256524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 256641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS, 256741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY)); 256841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 256941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 25704803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 257182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 257282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 257382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 25753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 257686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 25773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 257913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 25803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 258182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2582bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 258382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 25845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 25855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 25865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 25873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 258886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 25893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25905f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 25915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 259274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 25935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 25945f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 25955f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 259682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 259782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 25981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 25993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 260074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 26013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2603888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 26044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2605ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 26063e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 26073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 26083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 26093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 2611ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 2612ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 2613875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 26149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 26154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 26162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 26172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 261874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 261982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 262082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2621c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 262282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 262382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 2624ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 2625ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 2626ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 262782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 262882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2629c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2630b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2631b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2632ed985574148a938bc3af24442eead313cc62521cMathias Agopian hwc.getDpiY(HWC_DISPLAY_PRIMARY), 2633ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 263482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 263574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 263682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 263782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 263874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 263982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 264082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 264182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 264282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 264382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 264474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 264582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 264682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 264782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 264882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 26493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 265074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 26513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 265274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" h/w composer %s and %s\n", 265382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 26549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette (mDebugDisableHWC || mDebugRegion || mDaltonize 26559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette || mHasColorMatrix) ? "disabled" : "enabled"); 265674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 265782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 265882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 265982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 266082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 266182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 266282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 266513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 266648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 2667db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 266848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 266948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 267048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 267148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 267248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 267348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 267448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 267548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 267648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 267748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 267848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 267948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 268048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 2681cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2682cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 268363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 268463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 268563f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 268663f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 268763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 268863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 268963f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 269063f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 269163f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 269224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 269363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 269463f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 269563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 269663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 269763f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 269863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 269963f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 270063f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2706041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 2707698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 2709d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 2710d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 27112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2716a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 271799b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 271899b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2719e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2720375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2721375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 273199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 273299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2733e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 27341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 27351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 27361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2743b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 274499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2745375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2746375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2747375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2748e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2749375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 275401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 275535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 276053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 276153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 276453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2765cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2766cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2767cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2768e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2769e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2770e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2771e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2772cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 27754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 27764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 27774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 277853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 277953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 278053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 278153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 278253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 278353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2784a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2785a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2786a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2788a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2789a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 279101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2794b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 279512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 27994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 28004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2801ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 2802ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2803ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 2804ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 2805ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 2806ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 2807ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1: mDaltonizer.setType(Daltonizer::protanomaly); break; 2808ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break; 2809ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 3: mDaltonizer.setType(Daltonizer::tritanomaly); break; 2810ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2811ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 2812ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::correction); 2813ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 2814ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::simulation); 2815ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2816ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonize = n > 0; 2817ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 2818ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 28199c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 28209c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28219c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 28229c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 28239c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 28249c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix = n ? 1 : 0; 28259c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 28269c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 28279c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 28289c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 2829794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 2830794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t j = 0; j < 4; j++) { 2831794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette mColorMatrix[i][j] = data.readFloat(); 2832794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette } 28339c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28349c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 28359c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 28369c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28379c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 28389c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 28399c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2841f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 2842f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 2843f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 2844645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 2845645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 2846f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 2847f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 2848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 285353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 285487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 285599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 285653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 285753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 285859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 28592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 28602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 286159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 28622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 28632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 28642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 2865b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 2866b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 2867b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 2868b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 28692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 28702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 2871b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 2872b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 2873b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 2874b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2875b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 2876b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 2877b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 2878b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 2879b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2880b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 2881b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 2882b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 2883b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 2884b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 28852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 28862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 28872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 28882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 28892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 2890b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 28912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 28922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 28932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 28942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 28962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 28972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 28982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 28992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2901b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 2902b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 2903b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 29042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 29052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 2906c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 29072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 29082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 29092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 29102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 2911b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 2912b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 2913b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 2914b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 29152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 29162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 29172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 2918b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 2919b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 2920b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 29212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 29222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 29232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 2924c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 29252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2928b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 29292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 29302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 29312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 2932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 2933b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 2934b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 2935b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 2936c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng result = impl->asBinder()->transact(code, data[0], reply); 29372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 2938b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 29392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 29402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 2944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 2945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 2946b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 2947b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 2948b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitRequested(false) 2949b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 2950b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 2951b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 29522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 29532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 29542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 29552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 29562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 29572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 2959b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 29602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 2961aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 29622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 2963b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 2964b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 2965b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 29662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 29672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 29692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 29722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 2973c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 2974c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 2975c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 29762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 29782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 29792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 29812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 29822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29835ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 29845ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 29855ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 29865ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (!producer->asBinder()->localBinder()) { 29875ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian Mutex::Autolock _l(mStateLock); 29885ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 29895ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (hw->getSecureLayerVisible()) { 29905ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 29915ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian return PERMISSION_DENIED; 29925ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 29935ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 29945ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 2995c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 2996c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 2997c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 2998c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 2999c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3000c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3001c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3002c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3003c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3004c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3005c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3006c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3007c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3008c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3009c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3010c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3011c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3012c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3013c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3014c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3015c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 30162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 30172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 30182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 30192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3020c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 30212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 30222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3023c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3024c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 30252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 30262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 30272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 30282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 30292a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3030c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3031c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3032c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 30332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3034c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 30352a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3036c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3037c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotation(rotation), 30382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian result(PERMISSION_DENIED) 30392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 30402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 30422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 30432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 30452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 30462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3047c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3048c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3049c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 30502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result); 30512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 30522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30532a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 30542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30559eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // make sure to process transactions before screenshots -- a transaction 30569eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // might already be pending but scheduled for VSYNC; this guarantees we 30579eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // will handle it before the screenshot. When VSYNC finally arrives 30589eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // the scheduled transaction will be a no-op. If no transactions are 30599eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // scheduled at this time, this will end-up being a no-op as well. 30609eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian mEventQueue.invalidateTransactionNow(); 30619eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian 30622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 30632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 30642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 30652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 30662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 30682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 30692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 30702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3071c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3072c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotationFlags); 30732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 30752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 30762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 30772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3079118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3080118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3081180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3082180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3083180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3084c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3085180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 3086c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3087180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3088180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 30893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3090180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3091180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 3092180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 3093180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 3094180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const bool filtering = reqWidth != hw_w || reqWidth != hw_h; 3095180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3096c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3097c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3098c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3099c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3100c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3101c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3102c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3103c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3104c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3105c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3106c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3107784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (static_cast<uint32_t>(sourceCrop.right) > hw_w) { 3108be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3109c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3110c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3111c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3112c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3113784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (static_cast<uint32_t>(sourceCrop.bottom) > hw_h) { 3114be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3115c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3116c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3117180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 31183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3119180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3120180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3121c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3122c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 31233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3124180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3125180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 31263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3127180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3128180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3129180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3130180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3131180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 31321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3133180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3134180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3135180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3136180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3137c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3138180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3139180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3140180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3141180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3142180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3143180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3144180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // compositionComplete is needed for older driver 3145180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian hw->compositionComplete(); 3146931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3147180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3148180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3149180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 31502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 31512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 31522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3153c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3154c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3155c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 315674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3157fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3158fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3159180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 3160180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 3161180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 3162180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3163180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3164180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3165180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3166180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3167180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3168180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3169180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3170180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3171180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 31720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 31730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 317483cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 31750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 317674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 31770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian status_t result = NO_ERROR; 31780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) { 31793ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 31803ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 31812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 31820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 31830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 31844ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 31850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 31860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 31872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 31880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 31890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 31900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 31910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 31920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 31930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 31940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3195866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 31960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 31970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 31980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 31990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 32000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 32013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 32023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 32033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 32043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 32050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 32060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 32070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 32080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3209c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3210c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3211c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3212d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3213866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3214866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3215866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3216866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3217866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3218866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 32199707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 32209707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3221866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3222866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3223866399093f9f60e7305f291e688abb456bace710Riley Andrews } 32242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3225866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3226866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3227866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3228866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3229866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3230866399093f9f60e7305f291e688abb456bace710Riley Andrews } 32312d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3232866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3233866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3234866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3235866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3236866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3237866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3238866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3239866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3240866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3241866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3242866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3243866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3244866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3245866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 32462d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3247866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 32482d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 32492d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3250d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3251d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3252d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3253d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3254d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3255d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3256d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3257d555684cb36dfb959694db76962e570184f98838Mathias Agopian 32580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 32590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 32600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 32610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 32620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 32630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 32640aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 32650aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 326674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3267afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall // queueBuffer takes ownership of syncFd 3268866399093f9f60e7305f291e688abb456bace710Riley Andrews window->queueBuffer(window, buffer, syncFd); 326974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 32700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 32710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 327274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 32730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 327474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 327574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 327674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 327774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 327874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3279d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3280d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3281fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3282d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3283d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3284d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3285fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3286fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3287fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3288fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3289fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3290fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3291fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3292fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3293fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3294fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3295fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3296fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3297fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3298fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 329986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", 3300fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3301fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3302fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3303fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3304fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3305fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3306fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 33071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 33081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 331313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3319be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 332013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 332113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3322be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 33231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 33241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3325be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3326be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3327be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 33281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 33291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3330be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3331be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3332be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3333be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3336921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 33383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 333947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) { 3340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 33423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 334347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) { 3344da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3345da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 33477303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 334996f0819f81293076e652792794a961543e6750d7Mathias Agopian 3350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 33513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 33523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 33533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 33543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 33553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 33563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 33573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 33583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 33593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3360