SurfaceFlinger.cpp revision 148994e5f33ce240ff24ceb5bc0500b7f2001959
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h> 42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 45d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 46cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 52921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 560f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 58d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 591f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 62118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 65a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 66f33e4b6f13bc3ee2d2a4e1abd1ada171c70d3492Mathias Agopian#include "DisplayHardware/GraphicBufferAlloc.h" 67a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 71bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 8199b49840d309727678b77403d6cc9f920111623fMathias Agopian 8299b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8399b49840d309727678b77403d6cc9f920111623fMathias Agopian 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 8952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 92a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 1015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mBootFinished(false) 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 103a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 11463f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 11563f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 11663f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 11763f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 119c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 120c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 138a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 14613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 149a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1527e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 15596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 15696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 15796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 15896f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1638dfa92fef9759a881e96ee58d59875d35023aab9Andy McFaddensp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName) 164e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 1823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 1838dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 1903ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) { 191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return mDefaultDisplays[id]; 195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 202b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 207a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2083330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 214921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 219a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian GLuint texture; 226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageDestroyGLTexture(GLuint texture) 228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : texture(texture) { 229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian glDeleteTextures(1, &texture); 232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(texture)); 236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat( 239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian PixelFormat format, 242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 249cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian for (int i=0 ; i<n ; i++) { 251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint nativeVisualId = 0; 252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); 253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (nativeVisualId>0 && format == nativeVisualId) { 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian *outConfig = configs[i]; 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 269da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint attribs[] = { 271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 272f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // The rest of the attributes must be in this order and at the end 273f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // of the list; we rely on that for fallback searches below. 274cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian EGL_RED_SIZE, 8, 275cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian EGL_GREEN_SIZE, 8, 276cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian EGL_BLUE_SIZE, 8, 277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_RECORDABLE_ANDROID, EGL_TRUE, 278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE 279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 281f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 282f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 283f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 284f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // maybe we failed because of EGL_RECORDABLE_ANDROID 285f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID"); 286f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall attribs[NELEM(attribs) - 3] = EGL_NONE; 287f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 288f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 289f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 290f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 291f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // allow less than 24-bit color; the non-gpu-accelerated emulator only 292f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // supports 16-bit color 293f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed"); 294f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall attribs[NELEM(attribs) - 9] = EGL_NONE; 295f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 296f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 297f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 298f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 299f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // this EGL is too lame for Android 300f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGE("no suitable EGLConfig found, giving up"); 301f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 302f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall return 0; 303f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 304f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hallsuccess: 305f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy)) 306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 310a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 320a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 321a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 324a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 326cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display) { 327a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 328a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 333a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 3368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 3397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 3418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3539575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 3549575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 3559575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 3569575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3579575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3589575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3599575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3609575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 3619575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 389b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 39034a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 39134a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 393b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 395b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 396b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 397b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 399cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian EGLint format = mHwc->getVisualID(); 40034a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLConfig = selectEGLConfig(mEGLDisplay, format); 40134a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); 402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 403da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 404da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 405da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 406cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4073ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mDefaultDisplays[i] = new BBinder(); 4093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian mCurrentState.displays.add(mDefaultDisplays[i], 410cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian DisplayDeviceState(DisplayDevice::DisplayType(i))); 411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 413cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // The main display is a bit special and always exists 414cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // 415cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // if we didn't add it here, it would be added automatically during the 416cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // first transaction, however this would also create some difficulties: 417cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // 418cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // - there would be a race where a client could call getDisplayInfo(), 419cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for instance before the DisplayDevice is created. 420cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // 421cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // - we need a GL context current in a few places, when initializing 422cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // OpenGL ES (see below), or creating a layer, 423cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // or when a texture is (asynchronously) destroyed, and for that 424cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // we need a valid surface, so it's conveniant to use the main display 425cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for that. 426cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 427cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc); 428cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<SurfaceTextureClient> stc = new SurfaceTextureClient( 429cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); 430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 4313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDevice::DISPLAY_PRIMARY, 4323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], 433cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian stc, fbs, mEGLConfig); 4343ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw); 435a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 436cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 438cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 439cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian initializeGL(mEGLDisplay); 440d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 441028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 442028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventThread = new EventThread(this); 443028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventQueue.setEventThread(mEventThread); 444028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 44592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 44692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4478630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 450d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 451d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 45213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 45313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 45413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 455a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 456a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 4578b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4613ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 4623ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ? 4633ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 4643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 4653ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 466a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 467a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 468a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 469a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 470a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 471a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 472a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 473a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 474a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 475a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 476a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 477a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 478a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 479a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 480a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 482d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 483582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 484582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 486582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 488134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 489134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 490134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 491134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 494582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 495582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 496582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 498582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 500134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 503582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 504582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 505134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 506134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 507134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 508134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 509134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 510134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 511134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 512134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 513582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 514582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 515582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 516582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 517582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 518134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 519134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 520134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 521134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 522134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 523134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5249d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { 5251604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian int32_t type = BAD_VALUE; 5261604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 5271604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (display == mDefaultDisplays[i]) { 5281604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5301604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5311604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5321604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5331604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5341604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 535c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian const HWComposer& hwc(getHwComposer()); 5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float xdpi = hwc.getDpiX(type); 5391604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float ydpi = hwc.getDpiY(type); 5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5468b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5478b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5488b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5498b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5508b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5518b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5528b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5538b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5548b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5558b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5568b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type == DisplayDevice::DISPLAY_PRIMARY) { 5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // The density of the device is provided by a build property 5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float density = Density::getBuildDensity() / 160.0f; 5611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (density == 0) { 5621604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // the build doesn't provide a density -- this is wrong! 5631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // use xdpi instead 5641604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian ALOGE("ro.sf.lcd_density must be defined as a build property"); 5651604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density = xdpi / 160.0f; 5661604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5671604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (Density::getEmuDensity()) { 5681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // if "qemu.sf.lcd_density" is specified, it overrides everything 5691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian xdpi = ydpi = density = Density::getEmuDensity(); 5701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density /= 160.0f; 5711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = density; 5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: this needs to go away (currently needed only by webkit) 5751604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5761604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = hw->getOrientation(); 5771604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo); 5781604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } else { 5791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: where should this value come from? 5801604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian static const int TV_DENSITY = 213; 5811604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = TV_DENSITY / 160.0f; 5821604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = 0; 5838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5848b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5851604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->w = hwc.getWidth(type); 5861604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->h = hwc.getHeight(type); 5878b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->xdpi = xdpi; 5888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->ydpi = ydpi; 5891604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->fps = float(1e9 / hwc.getRefreshPeriod(type)); 590888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 591c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 592c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 593d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 594d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 595d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 5968aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 597bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 598bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 5999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) { 6003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian sp<IBinder> token; 6023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 6033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 6045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian token = mExtDisplayToken; 6053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 6063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6075f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian if (token == 0) { 6088dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden token = createDisplay(String8("Display from connectDisplay")); 6093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 6103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6115f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian { // scope for the lock 6125f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian Mutex::Autolock _l(mStateLock); 6135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian if (surface == 0) { 6145f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // release our current display. we're guarantee to have 6155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // a reference to it (token), while we hold the lock 6165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mExtDisplayToken = 0; 6175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } else { 6185f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mExtDisplayToken = token; 6195f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 6205f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 6215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian DisplayDeviceState& info(mCurrentState.displays.editValueFor(token)); 6225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian info.surface = surface; 6235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 6245f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 6253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 6263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 62899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 62999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 63099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 63199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 63299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 63399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 63499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 63599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 63699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 63799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 63899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 63999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 64099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 64199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 64299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 64399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 64499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 64599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 64699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 64799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 64899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 64999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 65099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 65199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 65299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 65399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 65499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 65599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 65699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 65799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 66199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 66299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 66543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden if (mEventThread == NULL) { 66643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // This is a temporary workaround for b/7145521. A non-null pointer 66743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // does not mean EventThread has finished initializing, so this 66843601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // is not a correct fix. 66943601a2dc320a271ff8c3765ff61414a07221635Andy McFadden ALOGW("WARNING: EventThread not started, ignoring vsync"); 67043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden return; 67143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 6723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 6733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian // we should only receive DisplayDevice::DisplayType from the vsync callback 674148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian mEventThread->onVSyncReceived(type, timestamp); 675148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 676148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 677148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 678148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 679148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 680148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 681148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 682148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 683148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 684148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 685148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 686148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 687148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // we should only receive DisplayDevice::DisplayType from the vsync callback 688148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian mEventThread->onHotplugReceived(type, connected); 6893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 6908630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 6918630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 6928630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) { 6938630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().eventControl(event, enabled); 6948630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 6958630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 6964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 6971c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 6994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 7054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 7064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 711e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 7124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 71387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 71987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 7204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 7213a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 7224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 731cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_2D); 751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_BLEND); 752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glColor4f(1, 0, 1, 1); 753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator it = dirtyRegion.begin(); 755cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator const end = dirtyRegion.end(); 756cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian while (it != end) { 757cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Rect& r = *it++; 758cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian GLfloat vertices[][2] = { 759cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.top }, 760cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.bottom }, 761cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.bottom }, 762cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.top } 763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian }; 764cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 765cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 766cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 767cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 768da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 770cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 771cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 773cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 775cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 776cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 777cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 778cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 779cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 780cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 781cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 782cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 783cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 784cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 785cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 786cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers[i]->onPreComposition()) { 787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 788cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 789cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 790cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 791cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 792cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 794a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 795cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 796cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 800cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian currentLayers[i]->onPostComposition(); 801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 803cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 804cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 80652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 80887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 80987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 810ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 81187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 81292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 813ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 814ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 815ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 8164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8177e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 8187e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 819ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (hw->canDraw()) { 820ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian SurfaceFlinger::computeVisibleRegions(currentLayers, 821ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 8227e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 823ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const size_t count = currentLayers.size(); 824ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 825ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 826ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const Layer::State& s(layer->drawingState()); 827ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 828ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region visibleRegion(tr.transform(layer->visibleRegion)); 829ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian visibleRegion.andSelf(bounds); 830ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (!visibleRegion.isEmpty()) { 831ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 832ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 83387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 83487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 8353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 8364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 8377e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 8387e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 8397e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 8403b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 8413b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 8433b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 84552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 84652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 84752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 84852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool workListsDirty = mHwWorkListDirty; 84952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mHwWorkListDirty = false; 85092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 8514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 852e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 853e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 854e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const Vector< sp<LayerBase> >& currentLayers( 855cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 856e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 857e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hwc.createWorkList(id, count) >= 0) { 858e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 859e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 860e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 861e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 862e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian 863e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (CC_UNLIKELY(workListsDirty)) { 864e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian layer->setGeometry(hw, *cur); 865e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (mDebugDisableHWC || mDebugRegion) { 866e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian cur->setSkip(true); 867e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian } 8681e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 86952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 870e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian /* 871e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian * update the per-frame h/w composer data for each layer 872e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian * and build the transparent region of the FB 873e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian */ 874e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian layer->setPerFrameData(hw, *cur); 875e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian } 8761e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 87752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 87887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 87952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 88052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 88152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 88352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 88652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 88792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 8884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 892cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 89352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // repaint the framebuffer (if needed) 894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDisplayComposition(hw, dirtyRegion); 89552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 897cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 89987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 90052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 9014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 9024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 90352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 908841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 909b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 910a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 911a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 912c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 91352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 914ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 9155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // FIXME: EGL spec says: 9165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // "surface must be bound to the calling thread's current context, 9175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // for the current rendering API." 918da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext); 919e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 92052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 92152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 92292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 9244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ()); 925da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 92652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 927e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 928e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 9291e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 9301e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 93152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 932d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 93352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 934cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 93552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 936d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 93752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 938ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 939e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 940e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 941a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 942a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 94587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 947841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 948841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 949ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 950ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 951ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 952ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 953ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 954ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 955ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 956ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 957ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 958ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 959e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 96087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 961ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 962ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 963ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 964ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 965ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 9663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 96887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 9693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 9703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 980076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 9913559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 994e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 99592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 99692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 99792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 998e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 999e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 100092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 100292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 100393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 100492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 100592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 100692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 100792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 100892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 100992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1010e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1011e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 101292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 10133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 10143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian mDisplays.removeItem(draw.keyAt(i)); 101592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 101692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 101792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 101892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 101992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1020e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 10213ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1022111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1023e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 102493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 102593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 102693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 102793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 102893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 102993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 103093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 103193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 103292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 103393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 103493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian const sp<DisplayDevice>& disp(getDisplayDevice(display)); 103593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 103693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 103793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 103893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 103900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 104000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 104100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 104200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 104300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 10444fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 104593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 10466905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 10476905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // Walk through all the layers in currentLayers, 10486905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // and update their transform hint. 10496905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // 10506905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // TODO: we could be much more clever about which 10516905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // layers we touch and how often we do these updates 10526905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // (e.g. only touch the layers associated with this 10536905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden // display, and only on a rotation). 10546905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden for (size_t i = 0; i < count; i++) { 10556905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden const sp<LayerBase>& layerBase = currentLayers[i]; 10566905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden layerBase->updateTransformHint(); 10576905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden } 105892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 105992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 106092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 106192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 106292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 106392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 106492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1065e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1066e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1067cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1068cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<FramebufferSurface> fbs; 1069cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<SurfaceTextureClient> stc; 1070cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (!state.isVirtualDisplay()) { 1071cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1072cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1073cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1074cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1075cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 1076cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1077cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1078cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1079cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian fbs = new FramebufferSurface(*mHwc); 1080cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian stc = new SurfaceTextureClient( 1081cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); 1082cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } else { 1083cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (state.surface != NULL) { 1084cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian stc = new SurfaceTextureClient(state.surface); 1085cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1086cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1087cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1088cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 1089cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (stc != NULL) { 1090cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 1091cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.type, display, stc, fbs, mEGLConfig); 1092cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1093cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 10944fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 10958dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1096cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 1097cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (hw->getDisplayType() < DisplayDevice::NUM_DISPLAY_TYPES) { 1098cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // notify the system that this display is now up 1099cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // (note onScreenAcquired() is safe to call from 1100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // here because we're in the main thread) 1101cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian onScreenAcquired(hw); 1102cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 110393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 110492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 110592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 11103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 11113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1113cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 1114cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers.size() > previousLayers.size()) { 11153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 11163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 11173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 11183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 11193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 11203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 11213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 11223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 11233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 11243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const size_t count = previousLayers.size(); 11253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 11263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 11273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 11283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 11293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 11303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 11313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 11321501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian const Layer::State& s(layer->drawingState()); 11331501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 11341501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 11351501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 11360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 11414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 11424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 11434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 11444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 11454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 11464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 11474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 11484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 11494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 11514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 11534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 11544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransationPending = false; 11554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 115987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 116087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1162841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1163841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 116887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 1172076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 1175970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian // only consider the layers on the given later stack 117887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 117987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 118087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1181ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1182ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1183ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1185ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1186ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1187ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1188ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1189ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1190ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1191ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1193ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1194ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1195ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1196ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1197ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1199ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1200ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1201ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1202da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 1203a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 12044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1206ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1207ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1208ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 12094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region transparentRegionScreen; 12104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 12114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 12124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 12134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 12144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = tr.transform(s.transparentRegion); 12154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 12164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 12174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 12184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen.clear(); 12194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 12204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 12214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = s.transparentRegion; 12224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 12234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian visibleRegion.subtractSelf(transparentRegionScreen); 1224ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1226ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 12274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1228ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1229ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1230ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1231ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1232ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1236ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1237ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1238ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1239ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1240ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1241ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 12504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1253a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1254ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1255ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1256ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1257ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1258ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1259ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1260ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1261ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1262ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1263ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1264a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1265ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 12664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 12674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1268ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1269ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 127487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1276ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 12788b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 128887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 128992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 12904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 12914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 12924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 129392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 129492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 129587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 129687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 129787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 12994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 130099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 1302cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 13034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 13044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 1305cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 130687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 13071501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian const Layer::State& s(layer->drawingState()); 130887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 13094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 13113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1314ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1315ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1316ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1317ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1318ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 131999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1320cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 132187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 132387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 132487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1325b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 13264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 13290f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 133029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 133129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 133229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 13334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 13350f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 133629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1337df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 133895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 13390f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 13404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 134229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 13434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 13444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1348cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, dirtyRegion); 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 13514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1352da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1353da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1354da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1357cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 135985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 13608630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 13611e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 13621e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1363a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 136485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end); 136585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1366da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 1367a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 136852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // set the frame buffer 136952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glMatrixMode(GL_MODELVIEW); 137052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glLoadIdentity(); 1371a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1372a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 137385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1374e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1375b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1376b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1377b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1378b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1379b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1380b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1381b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1382b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 13834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Region region(hw->undefinedRegion.intersect(dirty)); 1384b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 138587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1386b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 138755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1388b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1389a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 139085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 13914b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 139285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 139385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 139485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 13954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 139685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 139785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 139885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 139985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 140085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 140185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 1402a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 14034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 140485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 140585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 140685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 140785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 140885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 140985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && layer->isOpaque() 141085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1411cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1412cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1413cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1414cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 141585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 141685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 141785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1418cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 141985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1420a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1421da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1422da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1423da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 1424da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i); 1425da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1426da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1427cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1428a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 142985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 143085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 143185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 143285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 143385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 143485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 143585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 143685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 143785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 143885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 143985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 14404b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 14414b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 144455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, 144555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const Region& region) const 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1447f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1448b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1449f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1450b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1451f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 145255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 1453f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1454f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1455f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1456f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 145755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian GLfloat vertices[][2] = { 145855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.top }, 145955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.bottom }, 146055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.bottom }, 146155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.top } 146255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian }; 146355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1464f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1465f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146896f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 146996f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 14701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 147196f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 14724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 14734f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 147496f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1475921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1476921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 147796f0819f81293076e652792794a961543e6750d7Mathias Agopian 14784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 147996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 148096f0819f81293076e652792794a961543e6750d7Mathias Agopian 148196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 148296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 148396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 148496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 148596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 14863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian setTransactionFlags(eTransactionNeeded); 148796f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14973d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 15019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 150276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 150376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 15049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 150576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 150676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 150776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 15088c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 15092f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 15100b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 15113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 15123d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 151396f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 151496f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 15159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 15169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 15179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1518dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1519dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1520dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1521dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1522dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1528bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 153299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15378b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 15388b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 15398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 15408b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 15418b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 1542698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 154328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1549b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1550b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 155528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1557386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 155828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1559386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 156028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1562386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1563386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1564386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1565386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1566386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1567386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1568386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1569386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1570386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1571386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 157232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1573386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1574386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1575386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1581e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1582e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token)); 15843ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 1585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1587e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1591e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1592e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1593e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1596e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1597e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 159800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1600e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1601e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1602e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1605e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1607e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1608e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1609e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1610e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1611e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1612e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1613e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1614e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1615e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1616e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 1617e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 1618e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 1619e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1620e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1621e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1622e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 1623e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1624e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 1625e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 1626e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1627e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1628e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 1629e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1630e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1631e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 1632e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1633e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1634e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1635e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1636e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1637e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1638e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1639e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 1640e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 1641e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1642e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1643e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1644e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 1645e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1646e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1647e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1648e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 1649e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 1650e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1651e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1652e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 1653e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1654e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1655e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1656e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eVisibilityChanged) { 1657e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1658e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1659e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1660e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 1661e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 1662e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1663e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1664e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 1665e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1666e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1667e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 1668e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1669e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1670e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1671e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1672e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1673e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1674e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1675e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1676e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1677e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1678e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1679921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 16800ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 16810ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 16820ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 16833ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian uint32_t w, uint32_t h, PixelFormat format, 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1686076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 16886e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 16896e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1690921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 16916e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 16926e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 16936e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 16948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1695921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 16963165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 16973165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 16983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createNormalLayer(client, w, h, flags, format); 1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 17003165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceBlur: 17013165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 17023ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createDimLayer(client, w, h, flags); 1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 17043165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceScreenshot: 17053ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createScreenshotLayer(client, w, h, flags); 1706118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1709076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 171096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1711285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 171296f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 17148b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 171596f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 17171c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 171896f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1724921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 17253ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 172696f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 17271c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 173092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1736a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1737a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1738a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 17398f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1740a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1744a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1745a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1746a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1747a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1748a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 17493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<Layer> layer = new Layer(this, client); 1750f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 175199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1752921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1753076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1758921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 17593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 176096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17623ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerDim> layer = new LayerDim(this, client); 1763118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1764118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1765118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1766921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 17673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 1768118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1769118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 17703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, client); 1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1774921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 17759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 17769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 17779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 17789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 17798b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 17800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 17810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 17820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 17839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 17849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 178548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 17860aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 178796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1788b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 178948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 179048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 179148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 179213233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian setTransactionFlags(eTransactionNeeded); 179348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 17949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 17959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 17969a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 17979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1798921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1800759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1801ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1802ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1803ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1804ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1805ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1806ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1807ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1808ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1809ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1810ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1811e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1812ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1813f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1814e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1815ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1816ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1817ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1820b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1821b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 182213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 182313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // reset screen orientation 182413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 182513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 182613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 182700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian d.what = DisplayState::eDisplayProjectionChanged; 18283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]; 182913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 18304c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 18314c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 183213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 183313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 1834cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian onScreenAcquired(getDefaultDisplayDevice()); 183513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 183613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 183713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 183813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 183913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 184013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 184113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 184213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 184313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 184413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 184513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 184613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 184713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 184813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 184913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 185013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 185113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 1852cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { 18538e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 18548630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().acquire(); 18554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->acquireScreen(); 1856cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { 1857cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 1858cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenAcquired(); 1859cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 186020128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian mVisibleRegionsDirty = true; 186120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian repaintEverything(); 1862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1864cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { 18658e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 18664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->isScreenAcquired()) { 1867cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { 1868cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 1869cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 1870cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 18714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->releaseScreen(); 18728630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().release(); 1873ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian mVisibleRegionsDirty = true; 1874b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1875b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1876b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1877b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 18788e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1879b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1880b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1881b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1882b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1883b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1884cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: should this be per-display? 1885cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian flinger->onScreenAcquired(flinger->getDefaultDisplayDevice()); 1886b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1887b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1888b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1889b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1890b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18938e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1894b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1895b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1896b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1897b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1898b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1899cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: should this be per-display? 1900cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian flinger->onScreenReleased(flinger->getDefaultDisplayDevice()); 1901b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1902b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1903b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1904b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1905b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1906b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1907b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1908b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1909b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19121d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 191599b49840d309727678b77403d6cc9f920111623fMathias Agopian 191699b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 19239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 19249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 19259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 19269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 19279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 19289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 19299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 19309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 19319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 19328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 19339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 19349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 19359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 19369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 19379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 194025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 194125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 194225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 194325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 194425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 194525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 194635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 194725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 194825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 194925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 195025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 195182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 195282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 195335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 195525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 195625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 195725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 195825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 195925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 196035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 196125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 196682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 196748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 196882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 196982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 197048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 197182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 197282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 197382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 197482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 197548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 197625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 197725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 197825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 197925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 198025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 198125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 198225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 198325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 198425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 198525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 198625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 198725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 199182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 199382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 199482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 199648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 200182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 200282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 200382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 200482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 200582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 200682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 200782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 200882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 200982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2010ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 201125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 201225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 201325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 201425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 201525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 201625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 201725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 201825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 201925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 202025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 202125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 202225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 202325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 202425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 202525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 202625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 202725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 202825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 202925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 203082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 203182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 203282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 203382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 203482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 203582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 203682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 203782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 203882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2039bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 204082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 204182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 204282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 204382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 204482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 204582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 204682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 204782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 204882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 204982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 205082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2051bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 205282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 205382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 205482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 2055ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 205682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 205782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 205882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 205982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 206082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 206182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 206282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 20631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 206482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 20655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 20665f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 20675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 20688dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size()); 20698dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden result.append(buffer); 20705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 20715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 20721d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian hw->dump(result, buffer, SIZE); 20735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 20745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 20755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 207682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 207782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 20781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 207982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 208082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 20811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2082888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 20834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 208482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 208582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 208682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 208782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 208882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 208982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 2090d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 209182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 2092d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID)); 209382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 209473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 209582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 209682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 20979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 20984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 209982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 210082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 21014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getOrientation(), hw->canDraw()); 210282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 210382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 210482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 210582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2106c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 210782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 210882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 21098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian " y-dpi : %f\n", 211082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 211182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2112c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2113b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2114b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2115b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiY(HWC_DISPLAY_PRIMARY)); 211682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 211782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 211882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 211982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 212082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 212182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 212282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 212382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 212482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 212582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 212682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 212782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 212882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 212982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 213082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 213182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 213282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 213382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 213482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 213582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 213682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 213782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 213882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 213982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 21404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ()); 214182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 214282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 214382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 214482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 214582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 214682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 214963f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 215063f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 215163f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 215263f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 215363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 215463f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 215563f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 215663f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 215763f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 215863f165fd6b86d04be94d4023e845e98560504a96Keun young Park (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start"); 215963f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 216063f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 216163f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 216263f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 216363f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 216463f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 216563f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 216663f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2172698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 21748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 21758e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 2176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2180a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 218199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 218299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2184375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2185375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 21871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 21881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 21891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 21901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 21911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 21921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 21931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 21941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 219599b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 219699b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2197e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 21981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 21991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 22001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2207b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 220899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2209375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2210375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2211375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2212e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2213375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 221801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 221935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 222453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 222553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 222853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2229cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2230cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2231cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2236cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22384d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 22394d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 22404d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 22414d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 224253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 224353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 224453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 224553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 224653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 224753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2248a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2249a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2250a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2251a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2252a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2253a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 225501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2258b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 225912839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 22634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 22644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 227253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 227387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 227499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 227553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 227653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 227859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack, 2280118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2281118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2282118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 22833ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut); 2284118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2285118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 22863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack, 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 228922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 229022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 229159119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 229459119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 22953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian // FIXME: figure out what it means to have a screenshot texture w/ multi-display 22963ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 22974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 22984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 230059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 230159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 230259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 230359119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 230459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 230559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 230659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 230759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 230859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2309a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2310a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2314015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 231559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 231659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 231959119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 232059119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 232159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 232259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 232359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 232659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2328c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2329c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2332a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2333a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 23344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 2338fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian layer->draw(hw); 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 234059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 23414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2342118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 234659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 235259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23559d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display, 235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2358bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2359bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2361fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2362fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 23673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 23703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 23714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 23724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 23754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getSecureLayerVisible()) { 2376ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 23773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 23783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 23793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 23803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 2381ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h); 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 23833b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 2388fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian const bool filtering = sw != hw_w || sh != hw_h; 238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2390ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2391ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// sw, sh, minLayerZ, maxLayerZ); 2392c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2401fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2408c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2416ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2422f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 24233ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 24249575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 24273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const uint32_t z = layer->drawingState().z; 24283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 24293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(true); 24303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer->draw(hw); 24313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(false); 2432bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2447fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 246174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 246374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2472e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 24734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2474e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2475ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2476c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 247774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 248074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24819d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 248374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2484bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2485bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 24879d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown if (CC_UNLIKELY(display == 0)) 24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 24959d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown sp<IBinder> display; 24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2502bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2503bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 25069d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display, 250774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2508bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2509bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25109d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown : flinger(flinger), display(display), 2511bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2512bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2513bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 25219d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown result = flinger->captureScreenImplLocked(display, 2522bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 25289d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2538921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2539921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2540921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2541921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2542921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2543921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2544921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2545921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2546921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2548be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 2549921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2550921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2551be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2552be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t ls = l->currentState().layerStack; 2553be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t rs = r->currentState().layerStack; 2554be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 2555be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 2556be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2557921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2558921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2559be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 2560be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 2561be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2562be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 2563921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2564921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2565921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2566921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 25673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 25683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(DisplayDevice::DISPLAY_ID_INVALID) { 2569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 25713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 25723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(type), layerStack(0), orientation(0) { 2573da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 2574da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 2575b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 25767303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2577b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 257896f0819f81293076e652792794a961543e6750d7Mathias Agopian 2579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2580