SurfaceFlinger.cpp revision 47e45405d1533aa73307014f7bf371e118695cf3
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> 38c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 43e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 44392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 49d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 50cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 541c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 57ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 630f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 64faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 65d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 66d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 72a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 77875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 79875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 82fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 88ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 89ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 91faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1140a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12399b49840d309727678b77403d6cc9f920111623fMathias Agopian 12499b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12599b49840d309727678b77403d6cc9f920111623fMathias Agopian 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1274f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 131076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 133875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 136a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 1374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1398afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 141a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 146ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 147faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 148948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 1499c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mDaltonize(false), 1509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix(false) 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 152a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1568afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 157b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 15850210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 159b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1628afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 16663f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 16763f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 171c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 172c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 17699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 182a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 183a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 18899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 18999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 19213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 195a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1987e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 20196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 20296f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 20396f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 20496f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 209dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 210dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 2293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 2308dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 231dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2376c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2386c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 256692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 257692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2679e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 268e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 269e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 284a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2853330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 291921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 295a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 296a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 301921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 304921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 308921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 316faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 317faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3185167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3195167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const char* label) : 3200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mPhaseOffset(phaseOffset), 3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3235167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncOnLabel(String8::format("VsyncOn-%s", label)), 3245167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncEventLabel(String8::format("VSYNC-%s", label)), 3250a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mDispSync(dispSync) {} 326faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // Do NOT lock the mutex here so as to avoid any mutex ordering issues 331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // with locking it in the onDispSyncEvent callback. 332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis status_t err = mDispSync->addEventListener(mPhaseOffset, 334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3475167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3630a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 3640a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 3655167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 3760a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const nsecs_t mPhaseOffset; 3770a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 3785167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 3800a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex mMutex; 384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 390b65f32ebe2c86869b07ac1c986660dfb2187b7d3Jesse Hall status_t err; 391692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall Mutex::Autolock _l(mStateLock); 392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 393b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 39434a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 397b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 402875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // get a RenderEngine for the given display / config (can't fail) 40305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); 404875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 408da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 411cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4129e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 413f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // set-up the displays that are already connected 4159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 416dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool isSecure = true; 418692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked(type); 419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 421b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> producer; 422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> consumer; 423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza 426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, 427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza consumer); 42819e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall int32_t hwcId = allocateHwcDisplayId(type); 429f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 43019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall type, hwcId, mHwc->getFormat(hwcId), isSecure, token, 431b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza fbs, producer, 43205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 433f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 434c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 435f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 43786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGD("marking display %zu as acquired/unblanked", i); 4382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(HWC_POWER_MODE_NORMAL); 439f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 443cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 444a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // make the GLContext current so that we can create textures when creating Layers 445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // (which may happens before we render something) 446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 448028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 4490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4505167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden vsyncPhaseOffsetNs, true, "app"); 451faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mEventThread = new EventThread(vsyncSrc); 4520a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4535167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden sfVsyncPhaseOffsetNs, true, "sf"); 4540a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mSFEventThread = new EventThread(sfVsyncSrc); 4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mEventQueue.setEventThread(mSFEventThread); 456028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 457d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 460faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // set a fake vsync period if there is no HWComposer 461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mHwc->initCheck() != NO_ERROR) { 462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(16666667); 463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 46592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4678630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 46813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 471a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 472a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 4769e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ? 4773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 480a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 486875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 490875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 492a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 495d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 496582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 4972adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 4992adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder()); 5006710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (configs == NULL) { 5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 509692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5109e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 511692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5121604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5151604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 519c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5371604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 5397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const Vector<HWComposer::DisplayConfig>& hwConfigs = 5417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza getHwComposer().getConfigs(type); 5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza for (size_t c = 0; c < hwConfigs.size(); ++c) { 5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const HWComposer::DisplayConfig& hwConfig = hwConfigs[c]; 5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float xdpi = hwConfig.xdpi; 5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float ydpi = hwConfig.ydpi; 5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.w = hwConfig.width; 5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.h = hwConfig.height; 5777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.fps = float(1e9 / hwConfig.refresh); 58091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 58191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden 58291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 58391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.presentationDeadline = 59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->push_back(info); 6018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 605dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 6076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return getDisplayDevice(display)->getActiveConfig(); 6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 609dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 6116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 6126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 6136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 6146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 6156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 6176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 6186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 6236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 6276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 6286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 6296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 6406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 6416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 6426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 6436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mDisplay.get(), mMode); 6446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 6456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 6496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 6546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 655888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 656c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 657c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 658d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 659d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 660d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 661d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 662d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 663d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 664d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 665d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 666d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 667d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 668d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 669d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 670d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 671d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 672d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 6738aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 674bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 675bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 67799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 67899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 67999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 68099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 68199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 68299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 68399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 68499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 68599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 68699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 68799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 68899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 68999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 69199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 69299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 69399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 695c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 69699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 700c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 70199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7084f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 7094f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 7104f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 7114f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 714faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 715faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 716948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 717faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 718d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 719d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 720faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 72143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 722faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 723faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 724948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 725faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 726faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 727948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 728948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 729948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 730948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall ALOGE("resyncToHardwareVsync called when HW vsync unavailable"); 731948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 732948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 733948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 734faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const nsecs_t period = 735faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 736faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 737faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 738faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 739faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 740faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 741faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 742d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 743d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 744faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 745faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 746faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 747faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 748948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 749faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 750faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 751d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 752d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 753faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 754faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 755faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 756948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 757948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 758948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 759faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 760faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 762d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 763faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 764d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 765d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 766d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 767d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 768faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 769148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 770d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 771d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 772d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 773d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 774d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 775d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 776148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 777148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 778148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 779148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 780148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 781148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 782148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 783148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 784148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 785148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 7869e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 7879e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 7889e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 789692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 790692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 7919e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 792692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 793692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 7949e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 7959e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 7969e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 7979e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 7983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 7998630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 80181cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 802faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 80381cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 8048630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8058630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 8064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 8071c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 80899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 8099eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian case MessageQueue::TRANSACTION: 8109eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian handleMessageTransaction(); 8119eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian break; 8124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 8134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 8144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 8154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 8164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 8174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 8184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 8194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 8204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 8254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 82687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 8274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 83287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8343a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 8354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 838cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 847cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 850cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 853cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 855cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 856cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 857cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 858cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 8633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 8643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 8653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 867da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 870cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 877bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 878bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 879bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 880bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 881bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 882bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 887cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 8881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 8891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 8911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 892cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 897cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 900cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 901cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 9021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian layers[i]->onPostComposition(); 906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 9074b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 908faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const HWComposer& hwc = getHwComposer(); 909faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 910faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 911faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 912faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 913faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 914faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 915948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 916faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 917faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 918faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9195167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 920faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 9212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 922faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 923faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 924faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 925faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 9274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 9284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 929a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 9304b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 9314b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 9324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 9334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 9344b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 9354b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 9364b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 9374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 9384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 939cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 940cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 941cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 942cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 94352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 944cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 94587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 94687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 947ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 9481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 94992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 950ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 951ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 95213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Vector< sp<Layer> > layersSortedByZ; 9534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 9547e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 9557e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 9562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 9571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 958ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 9597e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 9601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 961ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 9621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 9631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 964ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 965a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 966a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 967a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 968a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 969ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 970ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 97187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 97287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 9733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 9757e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 9767e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 9777e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 9783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 9813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 982cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 983028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9847143316af216fa92c31a60d4407b707637382da1Dan Stoza bool mustRecompose = 9857143316af216fa92c31a60d4407b707637382da1Dan Stoza !(mDisplays[dpy]->getDirtyRegion(false).isEmpty()); 9867143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 987028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 988028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 98952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 99052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 99152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 992a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 993a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 994a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 995a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 996a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 997a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 999a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 1000a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 1001a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 1002a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1003a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1004a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1006a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 10079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { 1008a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 1009a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1010a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1011a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1012a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1013a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1014a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1015a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1016a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 101792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 10184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 1019e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 1020e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1022cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 1023e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 1024a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1025a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1026a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1027a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 1028a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 1029a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 1030a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1032a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 10331e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 103452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 103587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1036a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 103703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // If possible, attempt to use the cursor overlay on each display. 103803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 103903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 104003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 104103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id >= 0) { 104203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 104303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 104403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 104503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 104603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 104703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 104803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 104903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer->isPotentialCursor()) { 105003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews cur->setIsCursorLayerHint(); 105103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 105203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 105303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 105403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 105503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 105603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 105752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 105852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 105938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 106038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 106138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall sp<const DisplayDevice> hw(mDisplays[dpy]); 106238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall hw->prepareFrame(hwc); 106338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 106452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1065cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 106652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1067cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1068cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 106952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 107092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 10714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 10722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1073cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1074cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 107502b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 107602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 107702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 107802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1079cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1080cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1081cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 108287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 108352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 10844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 10854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 108652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1091841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1092b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1093a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1094a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1095c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 109652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 1097ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 10982a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 10992a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 11002a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 11012a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 1102875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11032a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 1104e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 110552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 110652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 11076da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // make the default display current because the VirtualDisplayDevice code cannot 11086da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // deal with dequeueBuffer() being called outside of the composition loop; however 11096da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // the code below can call glFlush() which is allowed (and does in some case) call 11106da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // dequeueBuffer(). 11116da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11126da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian 111392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1116da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 111752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 1118e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1119e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 11201e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 11211e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 112252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1123d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 112452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1125cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 112652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1127d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 112852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1129ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1130e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1131e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1132a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1133a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 11346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 11356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 11366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 11376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 11386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 114187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1143841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1144841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 11457cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 11467cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 11477cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 11487cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 11497cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 11507cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1151ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1152ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1153ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1154ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1155ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1156ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1157ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1158ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1159ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1160ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1161e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 116287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1163ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1164ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1165ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1166ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1167ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 11683d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 11713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 11723d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 11933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 119792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 119892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 119992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1200e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1201e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 120292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 120492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 120593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 120692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 120792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 120892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 120992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 121092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 121192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 121492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 12153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 121627ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 121727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 121827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 121902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1220875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 122102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 122202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 122302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 12249e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 12257adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 122602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 122792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 122892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 122992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 123092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 123192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 12333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1234111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 123693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 123793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 123893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 123902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 124002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 124102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 124293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 124393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 124493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 124593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 124693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 124792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 124893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1249db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 125093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 125193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 125293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 125393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 125400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 125500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 125600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 125700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 125800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 12594fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 126093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 126147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 126247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 126347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 126492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 126592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 126692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 126792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 126892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 126992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1273cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 127499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1275db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1276b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1277b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 1278b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 1279b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 1280db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 128102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall int32_t hwcDisplayId = -1; 128299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 128302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 128402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 128502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 128699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1287db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 128802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1289db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface( 1290b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *mHwc, hwcDisplayId, state.surface, 1291b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqProducer, bqConsumer, state.displayName); 1292db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1293db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 129447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 129599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 129699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1297cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1298cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1299cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1300cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 130102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1302cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1303cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1304b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza dispSurface = new FramebufferSurface(*mHwc, state.type, 1305b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqConsumer); 1306b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza producer = bqProducer; 1307cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1308cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1309cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 131099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1311cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 131219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall state.type, hwcDisplayId, 131319e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall mHwc->getFormat(hwcDisplayId), state.isSecure, 131405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall display, dispSurface, producer, 131505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1316cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1317cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 13184fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 13198dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1320cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 13211c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (state.isVirtualDisplay()) { 13221c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (hwcDisplayId >= 0) { 13231c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall mHwc->setVirtualDisplayProperties(hwcDisplayId, 13241c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getWidth(), hw->getHeight(), 13251c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getFormat()); 13261c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 13271c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } else { 13287adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 13291c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 133093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 133192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 133292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 13378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 13388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 13398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 13408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 13428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 13438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 13458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 13468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 13478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 13498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 13508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 13528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 13538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 13548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 13558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 13568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 13578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 13588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 13598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 13608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 13618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 136213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 13631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 13648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 13658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 13668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 13678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 13688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 13698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 13708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 13718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 13728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 13738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 13748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 13758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 137691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 13778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 13788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 13798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 13808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 13818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 138291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 138391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 138491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 138591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 138691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 138791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 138891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 138991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 13908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 139191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 13928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 13938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 13948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 13958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 13963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 13973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 13983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 14011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 14023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 14033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 14053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 14063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 14073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 14083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 14093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 14103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 14123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 14131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 14143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 14153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 14163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 14173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 14183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 14191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 14201501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 14211501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 14221501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 14230aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 142803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 142903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 143003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 143103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 143203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 143303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 143403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer& hwc(getHwComposer()); 143503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 143603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 143703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 143803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id < 0) { 143903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 144003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 144103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 144203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 144303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 144403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 144503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 144603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 144703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) { 144803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 144903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 145003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 145103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect cursorPos = layer->getPosition(hw); 145203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hwc.setCursorPositionAsync(id, cursorPos); 145303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 145403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 145503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 14574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 14584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 14594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 14604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 14614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 14624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 14634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 14644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 14654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 14664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 14674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 14684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 14694b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 14704b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 14714b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 14724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 14732d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 14742d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 14754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 147987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 148087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1482841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1483841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 148887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 149213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 14951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 149887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 149987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 150087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1501ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1502ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1503ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1505ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1506ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1507ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1508ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1509ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1510ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1511ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1513ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1514ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1515ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1516ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1517ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1519ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1520a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1521a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1522a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1523a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1524a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1525a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1526a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1527a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1528a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1529a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1530ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1531ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1532da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 15334125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 15345219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian Rect bounds(s.transform.transform(layer->computeBounds())); 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1536ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1537ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1538ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 15394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 15404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 15414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 15424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 15432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = tr.transform(s.activeTransparentRegion); 15444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 15454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 15464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1547a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 15484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 15502ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = s.activeTransparentRegion; 15514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1552ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1554ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 15554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1556ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1557ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1558ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1559ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1560ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1564ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1565ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1566ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1567ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1568ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1569ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 15784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1581a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1582ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1583ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1586ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1592a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 15944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 15954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 160287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 16068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1607a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1610a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1611a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 161487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 161787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 161887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 161992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 16204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 16214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 16224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 162392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 162492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 162587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 162687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 162787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 163099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 16314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 16321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 16331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 16344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 16351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 163687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 16371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 163887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 16394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16404da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 16413b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1644ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1645ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1646ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1647ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1648ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 164999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1650cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 165187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16537143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 16547143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 16557143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 16567143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 16577143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 16587143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 16597143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 16607143316af216fa92c31a60d4407b707637382da1Dan Stoza } 16617143316af216fa92c31a60d4407b707637382da1Dan Stoza 166287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 166387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1664b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 16654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 16680f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 166929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 167029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 167129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 16724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 16740f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 167529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1676df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 167795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 16780f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 16794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 168129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 16824297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 16834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16879c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { 1688ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1689ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 1690ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian RenderEngine& engine(getRenderEngine()); 16919c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mat4 colorMatrix = mColorMatrix; 16929c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDaltonize) { 16939c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette colorMatrix = colorMatrix * mDaltonizer(); 16949c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 16959c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette engine.beginGroup(colorMatrix); 1696ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1697ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian engine.endGroup(); 1698ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17009c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 17014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1702da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1703da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1704da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 171085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 17118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 17121e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 17131e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1714a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1715d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall bool hasGlesComposition = hwc.hasGlesComposition(id); 171685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1717875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) { 1718c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1719c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 1720c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock return; 1721c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1722a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1723a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 172485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1725e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1726b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1727b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1728b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 17293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 1730b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 17313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 0); 1732b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1733766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1734766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1735766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1736766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1737766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1738766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1739766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1740766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1741766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1742766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1743766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1744766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1745766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1746766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1747b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 174887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1749b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 175055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1751b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1752a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1753f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1754766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1755766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1756f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1757f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1758f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1759766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1760f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1761f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1762f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1763f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 17643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1765f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 17663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian const uint32_t height = hw->getHeight(); 17673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setScissor(scissor.left, height - scissor.bottom, 17683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 1769f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1770f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 177185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 17724b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 177385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 177485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 177585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 17764b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 177713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); 177885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 177985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 178085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 178185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 178285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 178313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 17844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 178585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 178685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 178703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews case HWC_CURSOR_OVERLAY: 178885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 1789ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 179085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 179185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 17924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden && layer->isOpaque(state) && (state.alpha == 0xFF) 179385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1794cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1795cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1796cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 179885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 179985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 180085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 180285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1803a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1804da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1805da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1806da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 180786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i); 1808da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1809da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1810cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1811a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 181285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 181385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 181485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 181585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 181685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 181713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 181885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 181985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 182085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 182185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 182285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 18234b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 18244b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1825f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1826f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 18273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableScissor(); 1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 183155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 18323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 18333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 1834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1836ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client, 1837ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 18386710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 183913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 18401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 184196f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 1842ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 18434f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 184496f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1845921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1846921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 18476710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mGraphicBufferProducerList.add(gbc->asBinder()); 184896f0819f81293076e652792794a961543e6750d7Mathias Agopian} 184996f0819f81293076e652792794a961543e6750d7Mathias Agopian 18503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { 185196f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 185213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 1853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 18546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mLayersPendingRemoval.push(layer); 1855076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 18566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian setTransactionFlags(eTransactionNeeded); 1857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 18593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1862c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 1863dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1864dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1865dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 18663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 1867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 187399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18788b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 18798b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 18808b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 18818b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 18828b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 18837c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 1884698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 188528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 18872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 18882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 18892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 18902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 18917c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 18922d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 18932d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 18947c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 18957c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 18967c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 18972d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 18982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 18992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19012d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19022d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1907b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1908b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1909e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1910698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1911698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1912d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 1913d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 1914d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 1915d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 1916d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 1917d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 1918d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 1919d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 1920d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<IBinder> binder = s.client->asBinder(); 1921d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 1922d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 1923d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 1924d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1925d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 1926d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1927d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1928d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1929698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1930386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 193128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1932386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 193328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1934698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1935386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1936386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1937386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 19382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 19392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 19402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 19412d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 1942386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 19432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 1944386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1945386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1946386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1947386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 19482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 19492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 1950386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1951386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1952cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 19589a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 19599a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 19609a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 19619a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 1962e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 19639a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 19643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 1965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1966e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1967e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1968e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1969e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1970e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1971e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1972e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1973e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1974e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1975e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1976e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1977e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 197800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 1979e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1980e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1981e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1982e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1984e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1985e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1988e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1989e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1990e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1991e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 199247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 199347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 199447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 199547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 199647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 199747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 199847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 199947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 200047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 200147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2002e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2003e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2004e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2005e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2006e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2007e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2008e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2009e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2010e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 201113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2012e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2013e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2014e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 2015e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 2016e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2017e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2018e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2019e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2020e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2021e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 2022e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2023e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2024e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2025e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2026e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2027e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2028e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2029e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2030e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2031e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2032e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2033e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2034e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 2035e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 2036e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2037e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2038e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2039e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2040e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2041e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2042e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2043e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2044e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2045e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 20464125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if ((what & layer_state_t::eVisibilityChanged) || 20474125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden (what & layer_state_t::eOpacityChanged)) { 20484125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden // TODO: should we just use an eFlagsChanged for this? 2049e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2050e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2051e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 2053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 2054e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2055e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2056e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2057e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2059e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 2060e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2061e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2062e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2063e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2064e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2065e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2066e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2067e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2068e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2069e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2070e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 20714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 20720ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 20730ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 20744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 20754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 20786e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2079921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 20806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 20814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 20826e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 20838b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 20844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 20854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 20864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 20874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 20883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 20893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 20904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 20914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 20924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 20943165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 20954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 20964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 20974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 20984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 20994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 21004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (result == NO_ERROR) { 21056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian addClientLayer(client, *handle, *gbp, layer); 210696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 2107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 21084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 21124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 21134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 211692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 21228f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 21274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 21284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 21294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2130b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 21324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 21334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 21344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 21384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 21394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 21424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2143b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 21444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2145118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2146118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2147ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 21489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 21496710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 21506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 21516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 21526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 21536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 21546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 21556710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 21569a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 21579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 21589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 21599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 216013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21626710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 21636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 2164ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 216513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> l(layer.promote()); 2166ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 21676710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 2168e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2169ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2170ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2171ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2174b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2175b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 217613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 217701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 217813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 217913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 218013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 218101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 218201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2183692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 218401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 218513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 21864c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 21874c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 218847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 218947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 219013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 219113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 21922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 21936547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 21946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const nsecs_t period = 21956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 21966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 219713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 219813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 219913a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 220013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 220113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 220213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 220313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 220413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 220513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 220613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 220713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 220813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 220913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 221013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 221113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 221213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 22132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 22142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 22152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 22162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 22172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 22182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 221913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 22202c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 22212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2222c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2223c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2224c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 22252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 22262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 22272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 22282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 22292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2230c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 22312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 22322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2233c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2234c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2235c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2236948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2237c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 22402c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 22412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2242c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2243948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2244948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2245cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2246cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2247cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2248c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 22492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 22502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 22512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 22522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 22532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2254b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 22582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2259db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2260db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 22612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2262b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 22632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 22642c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 22652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2266b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 22672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2268db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 22692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 22702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay.get(), mMode); 22719e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 22722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 22732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2274db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 22752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2276db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2277b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2278b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2279b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 22802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2281db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2282b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2283b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2284b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2285b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 228999b49840d309727678b77403d6cc9f920111623fMathias Agopian 2290bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2291bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2292bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2293bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2294bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 229574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2296bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 22989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 22999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 23009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 23019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 23029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 23039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 23049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 23059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 23069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 230774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append( 23089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 23099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 23109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 23119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 231282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 231382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 231425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 231525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 231625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 231725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 231825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 231974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 232035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 232125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 232225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 232325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 232425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 232582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 232674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 232735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 232882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 232925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 233025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 233125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 233225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 233374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 233435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 233525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2336c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2337c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2338c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2339c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2340c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2341c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2342c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 23441b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 234582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 234674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 234782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 234848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 234982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 235082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 235148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 235282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 235482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 235582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 235648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2357c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2358c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 235925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 236025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 236125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 236225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 236313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 236474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 236525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 236625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 236725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 236882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 236974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 237082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 237182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 237282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 237382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 237482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 237582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 237648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 23774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const nsecs_t period = 23784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 237986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 23804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 23814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2382d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 23834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 23844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 23854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 23864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 238713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 23884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2389d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 23904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 239282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2394ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 239525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2396c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 239725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 239825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 239925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 240025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 240125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 240225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 240325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 240425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 240525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 240625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 240713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 240825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2409d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 241025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 241125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 24124b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2413d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 241425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 241525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 24166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 24176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 24186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 24196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 24206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 24216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 24226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 24236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 24246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 24256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 24266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 24276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 24286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 24294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 24304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 24314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 24324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 24334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 24344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 24354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 24364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 24374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 24384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 24394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 24404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 24414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 24424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 24434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 24444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 24454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 244674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 244774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 244882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 24493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 24503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 24513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 24523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 24533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 24543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 24553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 24563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 24573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 245882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 245982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 246082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 246182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 246282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 246382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2464bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 246582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 24664803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 24674803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 24683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 24693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 24704803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 24713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 24724803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 24734803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 24744803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 24754803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 24764803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 24773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2478ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 24793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2480ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2481ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2482ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 248341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 248441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 248541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 248624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 248724cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 248841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS, 248941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY)); 249041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 249141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 24924803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 249382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 249482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 249582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 249682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 24973e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 249886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 24993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 250082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 250113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 25023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 250382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2504bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 250582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 25065f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 25075f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 25085f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 25093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 251086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 25113e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25125f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 25135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 251474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 25155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 25165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 25175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 251882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 251982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 25201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 25213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 252274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 25233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2525888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 25264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2527ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 25283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 25293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 25303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 25313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 2533ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 2534ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 2535875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 25369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 25374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 25382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 25392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 254074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 254182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 254282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2543c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 254482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 254582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 2546ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 2547ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 2548ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 254982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 255082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2551c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2552b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2553b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2554ed985574148a938bc3af24442eead313cc62521cMathias Agopian hwc.getDpiY(HWC_DISPLAY_PRIMARY), 2555ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 255682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 255774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 255882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 255982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 256074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 256182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 256282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 256382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 256482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 256582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 256674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 256782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 256882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 256982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 257082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 25713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 257274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 25733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 257474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" h/w composer %s and %s\n", 257582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 25769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette (mDebugDisableHWC || mDebugRegion || mDaltonize 25779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette || mHasColorMatrix) ? "disabled" : "enabled"); 257874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 257982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 258182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 258282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 258382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 258482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 258713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 258848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 2589db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 259048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 259148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 259248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 259348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 259448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 259548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 259648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 259748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 259848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 259948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 260048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 260148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 260248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 2603cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2604cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 260563f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 260663f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 260763f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 260863f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 260963f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 261063f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 261163f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 261263f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 261363f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 261424cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 261563f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 261663f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 261763f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 261863f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 261963f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 262063f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 262163f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 262263f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2628041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 2629698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 2631d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 2632d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 26332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2638a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 263999b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 264099b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2641e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2642375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2643375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 26451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 26461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 26471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 26481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 26491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 26501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 26511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 26521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 265399b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 265499b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2655e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 26561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 26571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 26581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 26591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 26621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2665b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 266699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2667375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2668375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2669375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2670e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2671375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 267601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 267735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 268253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 268353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 268653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2687cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2688cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2689cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2690e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2691e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2692e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2693e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2694cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 26964d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 26974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 26984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 26994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 270053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 270153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 270253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 270353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 270453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 270553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2706a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2707a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2708a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2709a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2710a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2711a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 271301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2716b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 271712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 27214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 27224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2723ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 2724ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2725ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 2726ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 2727ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 2728ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 2729ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1: mDaltonizer.setType(Daltonizer::protanomaly); break; 2730ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break; 2731ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 3: mDaltonizer.setType(Daltonizer::tritanomaly); break; 2732ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2733ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 2734ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::correction); 2735ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 2736ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::simulation); 2737ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2738ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonize = n > 0; 2739ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 2740ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 27419c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 27429c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 27439c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 27449c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 27459c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 27469c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix = n ? 1 : 0; 27479c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 27489c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 27499c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 27509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 2751794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 2752794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t j = 0; j < 4; j++) { 2753794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette mColorMatrix[i][j] = data.readFloat(); 2754794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette } 27559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 27569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 27579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 27589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 27599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 27609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 27619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2763f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 2764f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 2765f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 2766645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 2767645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 2768f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 2769f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 2770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 277553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 277687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 277799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 277853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 277953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 278059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 27812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 27822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 278359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 27842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 27852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 27862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 2787b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 2788b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 2789b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 2790b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 27912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 27922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 2793b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 2794b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 2795b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 2796b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2797b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 2798b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 2799b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 2800b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 2801b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2802b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 2803b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 2804b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 2805b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 2806b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 28072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 28082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 28092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 28102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 28112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 2812b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 28132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 28142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 28152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 28162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 28182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 28192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 28202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 28212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2823b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 2824b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 2825b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 28262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 28272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 2828c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 28292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 28302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 28312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 28322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 2833b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 2834b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 2835b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 2836b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 28372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 28382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 28392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 2840b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 2841b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 2842b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 28432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 28442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 28452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 2846c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 28472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 28482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2850b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 28512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 28522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 28532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 2854b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 2855b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 2856b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 2857b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 2858c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng result = impl->asBinder()->transact(code, data[0], reply); 28592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 2860b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 28612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 28622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 28632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 28642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 2866b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 2867b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 2868b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 2869b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 2870b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitRequested(false) 2871b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 2872b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 2873b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 28742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 28752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 28762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 28772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 28782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 28792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 28802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 2881b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 28822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 2883aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 28842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 2885b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 2886b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 2887b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 28882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 28892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 28902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 28912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 28932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 28942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 2895c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 2896c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 2897c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) { 28982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 28992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 29002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 29012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 29032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 29042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29055ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 29065ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 29075ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 29085ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (!producer->asBinder()->localBinder()) { 29095ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian Mutex::Autolock _l(mStateLock); 29105ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 29115ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (hw->getSecureLayerVisible()) { 29125ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 29135ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian return PERMISSION_DENIED; 29145ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 29155ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 29165ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 29172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 29182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 29192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 29202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 2921c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 29222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 29232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 2924c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 29252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 29262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 29272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 29282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 29292a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 2930c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 2931c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 2932c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) 29332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 2934c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 29352a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2936c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 29372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian result(PERMISSION_DENIED) 29382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 29392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 29402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 29412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 29422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 29432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 29442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 29452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 2946c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 2947c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 2948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform); 29492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result); 29502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 29512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 29522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 29532a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 29549eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // make sure to process transactions before screenshots -- a transaction 29559eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // might already be pending but scheduled for VSYNC; this guarantees we 29569eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // will handle it before the screenshot. When VSYNC finally arrives 29579eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // the scheduled transaction will be a no-op. If no transactions are 29589eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // scheduled at this time, this will end-up being a no-op as well. 29599eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian mEventQueue.invalidateTransactionNow(); 29609eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian 29612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 29622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 29632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 29642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 29652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 29672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 29682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 29692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 2970c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 2971c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza useIdentityTransform); 29722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 29742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 29752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 29762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 29772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 2978118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2979118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2980180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2981180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 2982180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 2983c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 2984180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 2985c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool yswap, bool useIdentityTransform) 2986180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 2987180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 29883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 2989180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2990180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 2991180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 2992180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 2993180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const bool filtering = reqWidth != hw_w || reqWidth != hw_h; 2994180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2995c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 2996c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 2997c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 2998c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 2999c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3000c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3001c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3002c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3003c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3004c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3005c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3006be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3007be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3008c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3009c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3010c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3011c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3012be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3013be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3014c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3015c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3016180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 30173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3018180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3019180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3020c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap); 30213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3022180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3023180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 30243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3025180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3026180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3027180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3028180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3029180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 30301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3031180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3032180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3033180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3034180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3035c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3036180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3037180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3038180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3039180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3040180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3041180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3042180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // compositionComplete is needed for older driver 3043180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian hw->compositionComplete(); 3044931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3045180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3046180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3047180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 30482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 30492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 30502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3051c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3052c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3053c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) 305474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3055fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3056fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3057180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 3058180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 3059180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 3060180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3061180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3062180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3063180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3064180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3065180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3066180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3067180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3068180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3069180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 30700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 30710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 307283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 30730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 307474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 30750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian status_t result = NO_ERROR; 30760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) { 30773ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 30783ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 30792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 30810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 30824ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 30830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 30840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 30852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 30870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 30880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 30890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 30900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 30910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 30920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 30930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 30940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 30950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 30960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 30970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 30983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 30993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 31003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 31013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 31020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 31030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 31040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 31050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3106c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight, 3107c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza minLayerZ, maxLayerZ, true, useIdentityTransform); 3108d555684cb36dfb959694db76962e570184f98838Mathias Agopian 31092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // Create a sync point and wait on it, so we know the buffer is 31102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // ready before we pass it along. We can't trivially call glFlush(), 31112d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // so we use a wait flag instead. 31122d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // TODO: pass a sync fd to queueBuffer() and let the consumer wait. 31132d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 31142d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 31152d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 31162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 31172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLint eglErr = eglGetError(); 31182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 31192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (result == EGL_TIMEOUT_EXPIRED_KHR) { 31202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW("captureScreen: fence wait timed out"); 31212d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 31222d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW_IF(eglErr != EGL_SUCCESS, 31232d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden "captureScreen: error waiting on EGL fence: %#x", eglErr); 31242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 31252d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 31262d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 31272d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // not fatal 31282d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 31292d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden 3130d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3131d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3132d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3133d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3134d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3135d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3136d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3137d555684cb36dfb959694db76962e570184f98838Mathias Agopian 31380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 31390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 31400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 31410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 31420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 31430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 31440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 31450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 314674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 31470aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian window->queueBuffer(window, buffer, -1); 314874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 31490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 31500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 315174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 31520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 315374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 315474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 315574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 315674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 315774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3158d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3159d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3160fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3161d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3162d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3163d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3164fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3165fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3166fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3167fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3168fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3169fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3170fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3171fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3172fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3173fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3174fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3175fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3176fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3177fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 317886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", 3179fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3180fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3181fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3182fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3183fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3184fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3185fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 31861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 31871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3188921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3189921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3190921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3191921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 319213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3193921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3194921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3195921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3196921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3198be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 319913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 320013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3201be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 32021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 32031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3204be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3205be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3206be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 32071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 32081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3209be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3210be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3211be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3212be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3213921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3214921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3215921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3216921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 32173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 321847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) { 3219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 32213ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 322247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) { 3223da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3224da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3225b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 32267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3227b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 322896f0819f81293076e652792794a961543e6750d7Mathias Agopian 3229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 32303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 32313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 32323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 32333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 32343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 32353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 32363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 32373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 32383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3239