SurfaceFlinger.cpp revision c8c71096195de0128e57574b1ddf685838ceb2f0
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> 404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h> 43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 47d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 48cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 521c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 580f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 59db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 60d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 611f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 64118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 68f33e4b6f13bc3ee2d2a4e1abd1ada171c70d3492Mathias Agopian#include "DisplayHardware/GraphicBufferAlloc.h" 69a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 72bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 73bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 8199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 8299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 8399b49840d309727678b77403d6cc9f920111623fMathias Agopian 8499b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8599b49840d309727678b77403d6cc9f920111623fMathias Agopian 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 9252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 95a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 99a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 1045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mBootFinished(false) 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 106a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 11763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 11863f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 11963f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 12063f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 122c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 123c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 139a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 140a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 141a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 14913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 152a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1557e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 15896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 15996f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16196f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 166dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 167dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 1863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 1878dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 188dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1946edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 1956edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 1966edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall "Overwriting display token for display type %d", type); 1976edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall mBuiltinDisplays[type] = new BBinder(); 1986edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall DisplayDeviceState info(type); 1996edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall // All non-virtual displays are currently considered secure. 2006edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall info.isSecure = true; 2016edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 2026edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall} 2036edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall 204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2053ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) { 206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 207e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 208e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2096edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall return mBuiltinDisplays[id]; 210e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 217b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 222a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2233330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2271f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2281f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2301f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2311f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2321f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 233a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 234a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 235a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 238921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 239921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 240921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian GLuint texture; 241921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 242921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageDestroyGLTexture(GLuint texture) 243921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : texture(texture) { 244921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 245921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 246921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian glDeleteTextures(1, &texture); 247921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 248921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 249921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 250921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(texture)); 251921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 252921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 253722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianstatus_t SurfaceFlinger::selectConfigForAttribute( 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 256722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint attribute, EGLint wanted, 257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 264cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 265722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (n) { 266722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (attribute != EGL_NONE) { 267722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian for (int i=0 ; i<n ; i++) { 268722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint value = 0; 269722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian eglGetConfigAttrib(dpy, configs[i], attribute, &value); 270722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (wanted == value) { 271722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian *outConfig = configs[i]; 272722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian delete [] configs; 273722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian return NO_ERROR; 274722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 275722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 276722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } else { 277722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian // just pick the first one 278722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian *outConfig = configs[0]; 279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 287722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianclass EGLAttributeVector { 288722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian struct Attribute; 289722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian class Adder; 290722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian friend class Adder; 291722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian KeyedVector<Attribute, EGLint> mList; 292722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian struct Attribute { 293722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian Attribute() {}; 294722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian Attribute(EGLint v) : v(v) { } 295722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint v; 296722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian bool operator < (const Attribute& other) const { 297722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian // this places EGL_NONE at the end 298722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint lhs(v); 299722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint rhs(other.v); 300722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (lhs == EGL_NONE) lhs = 0x7FFFFFFF; 301722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (rhs == EGL_NONE) rhs = 0x7FFFFFFF; 302722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian return lhs < rhs; 303722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 304722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian }; 305722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian class Adder { 306722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian friend class EGLAttributeVector; 307722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLAttributeVector& v; 308722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint attribute; 309722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian Adder(EGLAttributeVector& v, EGLint attribute) 310722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian : v(v), attribute(attribute) { 311722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 312722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian public: 313722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian void operator = (EGLint value) { 314722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (attribute != EGL_NONE) { 315722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian v.mList.add(attribute, value); 316722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 317722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 318722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian operator EGLint () const { return v.mList[attribute]; } 319722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian }; 320722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopianpublic: 321722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLAttributeVector() { 322722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian mList.add(EGL_NONE, EGL_NONE); 323722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 324722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian void remove(EGLint attribute) { 325722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (attribute != EGL_NONE) { 326722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian mList.removeItem(attribute); 327722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 328722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 329722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian Adder operator [] (EGLint attribute) { 330722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian return Adder(*this, attribute); 331722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 332722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLint operator [] (EGLint attribute) const { 333722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian return mList[attribute]; 334722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian } 335722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian // cast-operator to (EGLint const*) 336722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian operator EGLint const* () const { return &mList.keyAt(0).v; } 337722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian}; 338722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian 339a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 345da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 346722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGLAttributeVector attribs; 347722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT; 348722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE; 349722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE; 350722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_RED_SIZE] = 8; 351722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_GREEN_SIZE] = 8; 352722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs[EGL_BLUE_SIZE] = 8; 353722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian 354722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config); 355722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian if (!err) 356722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian goto success; 357722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian 358722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian // maybe we failed because of EGL_FRAMEBUFFER_TARGET_ANDROID 359722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian ALOGW("no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID"); 360722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID); 361722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian err = selectConfigForAttribute(display, attribs, 362722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 363f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 364f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 365f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 366f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // maybe we failed because of EGL_RECORDABLE_ANDROID 367f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID"); 368722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs.remove(EGL_RECORDABLE_ANDROID); 369722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian err = selectConfigForAttribute(display, attribs, 370722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 371f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 372f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 373f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 374f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // allow less than 24-bit color; the non-gpu-accelerated emulator only 375f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // supports 16-bit color 376f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed"); 377722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs.remove(EGL_RED_SIZE); 378722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs.remove(EGL_GREEN_SIZE); 379722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian attribs.remove(EGL_BLUE_SIZE); 380722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian err = selectConfigForAttribute(display, attribs, 381722b98f9dfe8f04de8734630198b99a6cd024118Mathias Agopian EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 382f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (!err) 383f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall goto success; 384f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 385f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall // this EGL is too lame for Android 386f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall ALOGE("no suitable EGLConfig found, giving up"); 387f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 388f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall return 0; 389f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall 390f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hallsuccess: 391f21cffa7d707dad10b2974c58c91482f7ca689acJesse Hall if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy)) 392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 396a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 400a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 401a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 403a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 409a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 410a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display) { 413a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 414a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 415a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 416a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 417a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 418a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 420a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 4228b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 423a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 424a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 4257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 4278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 433a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 434a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 435a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 436a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4399575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 4409575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 4419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 4429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 4459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 4469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 4479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 456a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 457a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 458a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 459a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 460a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 461a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 462a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 463a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 464a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 465a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 466a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 467a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 468a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 469a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 470a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 471a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 472a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 473a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 474a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4756edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall Mutex::Autolock _l(mStateLock); 4766edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall 477b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 47834a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 47934a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 480a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 481b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 482b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 483b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 484b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 485b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 487cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian EGLint format = mHwc->getVisualID(); 48834a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLConfig = selectEGLConfig(mEGLDisplay, format); 48934a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); 490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 491da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 492da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 493da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 494cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 496f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 497f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // set-up the displays that are already connected 4989e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 499dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 500dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool isSecure = true; 5016edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall createBuiltinDisplayLocked(type); 5026edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 5036edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall 504f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); 505f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<SurfaceTextureClient> stc = new SurfaceTextureClient( 506f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); 507f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 508dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis type, isSecure, token, stc, fbs, mEGLConfig); 509f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 510c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 511f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 512f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 513c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("marking display %d as acquired/unblanked", i); 514f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian hw->acquireScreen(); 515f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 516f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 517f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 519cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 520f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // we need a GL context current in a few places, when initializing 521f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // OpenGL ES (see below), or creating a layer, 522f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // or when a texture is (asynchronously) destroyed, and for that 523f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // we need a valid surface, so it's convenient to use the main display 524f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for that. 525db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 526cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 527a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 528cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 529cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian initializeGL(mEGLDisplay); 530d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 531028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 532028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventThread = new EventThread(this); 533028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventQueue.setEventThread(mEventThread); 534028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 53592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 53692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 5378630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 538cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 539a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 540d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 541d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 54213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 54313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 54413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 545a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 546a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 5478b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5513ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 5523ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ? 5533ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 5543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 5553ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 556a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 557a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 558a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 559a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 560a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 561a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 562a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 563a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 564a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 565a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 566a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 567a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 568a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 569a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 570a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 572d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 573582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 574582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 575134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 576582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 577134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 578134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 579134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 580134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 581134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 582134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 583134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 584582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 585582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 586582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 587582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 588582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 589134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 590134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 591134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 592134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 593582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 594582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 595134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 596134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 597134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 598134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 599134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 600134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 601134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 602134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 603582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 604582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 605582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 606582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 607582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 608134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 609134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 610134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 611134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 612134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 613134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 6149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { 6156edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall int32_t type = NAME_NOT_FOUND; 6161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 6176edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall if (display == mBuiltinDisplays[i]) { 6181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 6191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 6201604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6211604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6221604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6231604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 6241604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 625c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 6268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian const HWComposer& hwc(getHwComposer()); 6281604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float xdpi = hwc.getDpiX(type); 6291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float ydpi = hwc.getDpiY(type); 6308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 6328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 6338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 6348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 6358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 6368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 6378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 6388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 6408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 6428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 6438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 6448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 6458b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 6468b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 6471604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6481604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type == DisplayDevice::DISPLAY_PRIMARY) { 6491604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // The density of the device is provided by a build property 6501604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float density = Density::getBuildDensity() / 160.0f; 6511604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (density == 0) { 6521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // the build doesn't provide a density -- this is wrong! 6531604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // use xdpi instead 6541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian ALOGE("ro.sf.lcd_density must be defined as a build property"); 6551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density = xdpi / 160.0f; 6561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (Density::getEmuDensity()) { 6581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // if "qemu.sf.lcd_density" is specified, it overrides everything 6591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian xdpi = ydpi = density = Density::getEmuDensity(); 6601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density /= 160.0f; 6611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6621604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = density; 6631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6641604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: this needs to go away (currently needed only by webkit) 6651604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 6661604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = hw->getOrientation(); 6671604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo); 6681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } else { 6691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: where should this value come from? 6701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian static const int TV_DENSITY = 213; 6711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = TV_DENSITY / 160.0f; 6721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = 0; 6738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6751604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->w = hwc.getWidth(type); 6761604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->h = hwc.getHeight(type); 6778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->xdpi = xdpi; 6788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->ydpi = ydpi; 6791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->fps = float(1e9 / hwc.getRefreshPeriod(type)); 680dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 681dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 682dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info->secure = true; 683dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 684888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 685c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 686c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 687d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 688d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 689d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 6908aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 691bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 692bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 69499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 69699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 70099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 70199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 72099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 72299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 72799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 72899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 73143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden if (mEventThread == NULL) { 73243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // This is a temporary workaround for b/7145521. A non-null pointer 73343601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // does not mean EventThread has finished initializing, so this 73443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden // is not a correct fix. 73543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden ALOGW("WARNING: EventThread not started, ignoring vsync"); 73643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden return; 73743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 7383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 7393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian // we should only receive DisplayDevice::DisplayType from the vsync callback 740148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian mEventThread->onVSyncReceived(type, timestamp); 741148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 742148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 743148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 744148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 745148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 746148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 747148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 748148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 749148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 750148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 751148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 7529e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 753148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 7549e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 7556edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall if (connected) { 7566edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 7579e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 7586edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 7596edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall mBuiltinDisplays[type].clear(); 7609e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 7619e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 7629e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 7639e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 7643ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 7658630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 7668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 76781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 76881cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 7698630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 7708630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 7721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 77399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 7754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 7764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 7774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 7784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 7804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 7814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 786e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 7874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 78887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 7894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 79487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 7954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 7963a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 7974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 800cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 803cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 804cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 806cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 808cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 809cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 810cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 811cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 812cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 815cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 816cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 819cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 820cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 821cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 822cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 823cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 824cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_2D); 826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_BLEND); 827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glColor4f(1, 0, 1, 1); 828cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator it = dirtyRegion.begin(); 830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator const end = dirtyRegion.end(); 831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian while (it != end) { 832cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Rect& r = *it++; 833cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian GLfloat vertices[][2] = { 834cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.top }, 835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.bottom }, 836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.bottom }, 837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.top } 838cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian }; 839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 843da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 847cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 850cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 853bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 854bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 855bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 856bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 857bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 858bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 863cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 865cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 867cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers[i]->onPreComposition()) { 868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 870cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 875a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian currentLayers[i]->onPostComposition(); 882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 88752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 88987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 89087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 891ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 89287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 89392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 894ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 895ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 896ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 8974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8987e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 8997e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 900ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (hw->canDraw()) { 901ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian SurfaceFlinger::computeVisibleRegions(currentLayers, 902ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 9037e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 904ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const size_t count = currentLayers.size(); 905ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 906ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 907ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian const Layer::State& s(layer->drawingState()); 908ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 909a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 910a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 911a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 912a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 913ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 914ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 91587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 91687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 9173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 9197e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 9207e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 9217e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 9223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 9233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 9253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 92752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 92852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 92952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 930a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 931a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 932a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 933a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 934a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 935a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 936a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const Vector< sp<LayerBase> >& currentLayers( 937a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 938a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 939a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 940a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 941a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 942a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 943a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 944a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 945a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (mDebugDisableHWC || mDebugRegion) { 946a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 947a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 948a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 949a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 950a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 951a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 952a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 953a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 954a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 95592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 957e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 958e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 959e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const Vector< sp<LayerBase> >& currentLayers( 960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 961e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 962a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 963a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 964a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 965a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 966a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 967a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 968a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 969a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 970a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 9711e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 97252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 97387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 974a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 97552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 97652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 97752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 978cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 97952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 981cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 98252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 98392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 987cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 98802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 98902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 99002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 99102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 992cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 993cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 994cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 99587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 99652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 9974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 9984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 99952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1004841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1005b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1006a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1007a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1008c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 100952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 1010ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 10112a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 10122a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 10132a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 10142a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 10152a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, 10162a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian getDefaultDisplayDevice(), mEGLContext); 10172a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 1018e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 101952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 102052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 102192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 10224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 10234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1024da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 102552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 1026e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1027e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 10281e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 10291e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 103052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1031d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 103252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1033cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 103452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1035d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 103652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1037ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1038e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1039e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1040a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1041a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1046841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1047841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1048ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1049ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1050ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1051ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1052ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1053ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1054ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1055ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1056ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1057ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 105987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1060ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1061ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1062ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1063ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1064ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 10653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 10683d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 10693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 10798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 10903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 109492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 109592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 109692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 109992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 110192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 110293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 110392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 110492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 110592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 110692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 110792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 110892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1110e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 111192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 11123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 111327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 111427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 111527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 1116db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 111727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 11183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian mDisplays.removeItem(draw.keyAt(i)); 111927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden getHwComposer().disconnectDisplay(draw[i].type); 11209e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden mEventThread->onHotplugReceived(draw[i].type, false); 112192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 112292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 112392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 112492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 112592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1126e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 11273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1128111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1129e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 113093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 113193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 113293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 113393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 113493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 113593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 113693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 113793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 113892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 113993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 114193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 114293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 114393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 114493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 114500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 114600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 114700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 114800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 114900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 11504fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 115193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 115292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 115392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 115492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 115592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 115692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 115792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 115892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1160e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1161cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1162cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<FramebufferSurface> fbs; 1163cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<SurfaceTextureClient> stc; 1164cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (!state.isVirtualDisplay()) { 1165cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1166cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1167cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1168cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1169cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 1170cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1171cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1172cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1173f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian fbs = new FramebufferSurface(*mHwc, state.type); 1174cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian stc = new SurfaceTextureClient( 1175dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis static_cast< sp<ISurfaceTexture> >( 1176dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis fbs->getBufferQueue())); 1177cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } else { 1178cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (state.surface != NULL) { 1179cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian stc = new SurfaceTextureClient(state.surface); 1180cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1181cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1182cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1183cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 1184cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian if (stc != NULL) { 1185cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 11866edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall state.type, state.isSecure, display, stc, fbs, 1187dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis mEGLConfig); 1188cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1189cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 11904fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 11918dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1192cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 11939e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden mEventThread->onHotplugReceived(state.type, true); 119493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 119592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 119692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 12018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 12028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 12038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 12048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 12068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 12078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 12098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 12108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 12118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 12138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 12148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 12168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 12178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 12188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 12198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 12218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 12228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 12238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 12248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 12258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 12268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<LayerBase>& layerBase(currentLayers[i]); 12278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t layerStack = layerBase->drawingState().layerStack; 12288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 12298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 12308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 12318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 12328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 12338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 12348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 12358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 12368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 12378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 12388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 12398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 12408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = getDefaultDisplayDevice(); 12418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 12428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp != NULL) { 12478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // presumably this means this layer is using a layerStack 12488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // that is not visible on any display 12498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian layerBase->updateTransformHint(disp); 12508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 12548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 12553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 12563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 12573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1259cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 1260cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers.size() > previousLayers.size()) { 12613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 12623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 12633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 12643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 12653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 12663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 12673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 12683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 12693559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 12703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const size_t count = previousLayers.size(); 12713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 12723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 12733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 12743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 12753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 12763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 12773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 12781501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian const Layer::State& s(layer->drawingState()); 12791501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 12801501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 12811501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 12820aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 12874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 12884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 12894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 12904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 12914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 12924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 12934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 12944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 12954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 12964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 12974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 12984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 12994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 13002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 13012d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 13024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 130687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 130787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1309841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1310841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 131587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 1319076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 1322970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 132487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian // only consider the layers on the given later stack 132587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 132687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 132787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1328ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1329ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1330ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1332ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1333ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1334ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1335ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1336ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1337ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1338ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1340ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1341ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1342ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1343ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1344ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1346ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1347a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1348a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1349a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1350a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1351a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1352a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1353a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1354a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1355a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1356a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1357ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1358ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1359da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 1360a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 13614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1363ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1364ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1365ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 13664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 13674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 13684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 13694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 1370a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion = tr.transform(s.transparentRegion); 13714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 13724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 13734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1374a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 13754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 1377a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion = s.transparentRegion; 13784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1379ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1381ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 13824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1383ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1384ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1385ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1386ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1387ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1391ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1392ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1393ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1394ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1395ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1396ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 14054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1408a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1409ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1410ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1411ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1412ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1413ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1414ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1415ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1416ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1417ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1418ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1419a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1420ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 14214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 14224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1423ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1424ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 142987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1431ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 14338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1434a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1437a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1438a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 144187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 144487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 144587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 144692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 14484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 14494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 145092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 145192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 145287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 145387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 145487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 145799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 1459cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 14604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 14614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 1462cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 146387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 14641501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian const Layer::State& s(layer->drawingState()); 146587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 14664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 14674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 14683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1471ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1472ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1473ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1474ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1475ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 147699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1477cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 147887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 148087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 148187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1482b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 14834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 14860f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 148729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 148829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 148929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 14904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 14920f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 149329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1494df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 149595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 14960f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 14974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 149929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 15004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 15014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1505cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, dirtyRegion); 1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15079c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 15084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1509da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1510da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1511da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1514cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 151685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 15178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 15181e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 15191e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1520a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 152185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end); 152285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1523c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock if (!DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext)) { 1524c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1525c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 1526c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock return; 1527c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1528a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 152952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // set the frame buffer 153052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glMatrixMode(GL_MODELVIEW); 153152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glLoadIdentity(); 1532a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1533a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 153485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1535e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1536b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1537b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1538b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1540b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1541b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1542b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1543b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 15444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Region region(hw->undefinedRegion.intersect(dirty)); 1545b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 154687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1547b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 154855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1549b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1550a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1551f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1552f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (hw->getDisplayType() >= DisplayDevice::DISPLAY_EXTERNAL) { 1553f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // TODO: just to be on the safe side, we don't set the 1554f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1555f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1556f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1557f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Transform& tr(hw->getTransform()); 1558f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect scissor(tr.transform(hw->getViewport())); 1559f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1560f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1561f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1562f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 1563f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const GLint height = hw->getHeight(); 1564f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glScissor(scissor.left, height - scissor.bottom, 1565f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian scissor.getWidth(), scissor.getHeight()); 1566f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // clear everything unscissored 1567f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glClearColor(0, 0, 0, 0); 1568f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1569f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 1570f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glEnable(GL_SCISSOR_TEST); 1571f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1572f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 157385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 15744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 157585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 157685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 157785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 15784b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 157985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 158085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 158185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 158285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 158385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 158485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 1585a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 15864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 158785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 158885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 158985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 159085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 159185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 159285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && layer->isOpaque() 159385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1594cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1595cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1596cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1597cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 159885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 159985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 160085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1601cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 160285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1603a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1604da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1605da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1606da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 1607da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i); 1608da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1609da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1610cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1611a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 161285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 161385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 161485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 161585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 161685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 161785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 161885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 161985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 162085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 162185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 162285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 16234b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 16244b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1625f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1626f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 1627f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glDisable(GL_SCISSOR_TEST); 1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, 163155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const Region& region) const 1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1633f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1634b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1635f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1636b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1637f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 163855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 1639f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1640f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1641f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1642f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 164355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian GLfloat vertices[][2] = { 164455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.top }, 164555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.bottom }, 164655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.bottom }, 164755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.top } 164855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian }; 164955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1650f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1651f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 165596f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 16561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 165796f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 16584f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 16594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 166096f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1661921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1662921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 166396f0819f81293076e652792794a961543e6750d7Mathias Agopian 16644f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 166596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 166696f0819f81293076e652792794a961543e6750d7Mathias Agopian 166796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 166896f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 166996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 167096f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 167196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 16723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian setTransactionFlags(eTransactionNeeded); 167396f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1676076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1680076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 16879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 168876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 168976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 16909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 169176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 169276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 169376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 16948c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 16952f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 16960b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 16973d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 16983d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 169996f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 170096f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 17019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 17029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 17039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1704dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1705dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1706dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1707dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1708dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1714bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 171899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17238b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 17248b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 17258b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 17268b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 17278b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 17287c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 1729698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 173028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1731e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 17322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 17342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 17352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 17367c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 17372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 17382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 17397c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 17407c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 17417c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 17422d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 17432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 17442d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 1748e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1749e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1750e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1751e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1752b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1753b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1755698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1756698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1757d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 1758d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 1759d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 1760d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 1761d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 1762d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 1763d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 1764d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 1765d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<IBinder> binder = s.client->asBinder(); 1766d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 1767d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 1768d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 1769d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1770d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 1771d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1772d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1773d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1774698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1775386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 177628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1777386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 177828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1779698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1780386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1781386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1782386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 17832d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 17842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 1787386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 17882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 1789386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1790386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1791386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1792386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 17932d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 17942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 1795386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1796386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1797cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1801e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1802e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 18039a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 18049a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 18059a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 18069a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 1807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 18089a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 18093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 1810e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1811e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1812e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1814e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 182300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 1824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1828e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1829e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1833e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1834e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 1842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 1843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 1844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 1850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 1851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1852e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 1854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 1857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 1865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 1870e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 1874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eVisibilityChanged) { 1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 1887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1904921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 19050ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 19060ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 19070ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 19083ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian uint32_t w, uint32_t h, PixelFormat format, 1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1911076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1912a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 19136e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 19146e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1915921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 19166e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 19176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 19186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 19198b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1920921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 19213165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 19223165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 19233ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createNormalLayer(client, w, h, flags, format); 1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 19253165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceBlur: 19263165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 19273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createDimLayer(client, w, h, flags); 1928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 19293165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceScreenshot: 19303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createScreenshotLayer(client, w, h, flags); 1931118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1934076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 193596f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1936285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 193796f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 19398b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 194096f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1941a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 19421c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 194396f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1949921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 19503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 195196f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 19521c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 195592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 1956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1961a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1962a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1963a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 19648f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1965a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1969a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1970a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1971a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1972a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1973a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 19743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<Layer> layer = new Layer(this, client); 1975f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 197699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1977921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1978076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1983921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 19843ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 198596f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19873ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerDim> layer = new LayerDim(this, client); 1988118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1989118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1990118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1991921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 19923ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 1993118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1994118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 19953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, client); 1996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1999921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 20009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 20019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 20029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 20039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 20048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 20050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 20060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 20070aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 20089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 20099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 201048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 20110aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 201296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 2013b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 201448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 201548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 201648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 201713233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian setTransactionFlags(eTransactionNeeded); 201848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 20199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 20209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 20219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 20229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 2023921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 2024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2025759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 2026ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 2027ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 2028ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 2029ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 2030ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 2031ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 2032ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 2033ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 2034ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 2035ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 2036e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 2037ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 2038f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 2039e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2040ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2041ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2042ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2045b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2046b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 204713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 204813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // reset screen orientation 204913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 205013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 205113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 205200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian d.what = DisplayState::eDisplayProjectionChanged; 20536edebdf6003d7efdbf9ca5dc83fef17b750693f1Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 205413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 20554c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 20564c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 205713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 205813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 2059cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian onScreenAcquired(getDefaultDisplayDevice()); 206013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 206113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 206213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 206313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 206413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 206513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 206613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 206713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 206813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 206913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 207013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 207113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 207213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 207313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 207413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 207513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 207613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 2077cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { 2078c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this); 2079c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (hw->isScreenAcquired()) { 2080c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // this is expected, e.g. when power manager wakes up during boot 2081c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously acquired"); 2082c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2083c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2084c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 20854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->acquireScreen(); 2086c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 2087c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 2088c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2089c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().acquire(type); 2090c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2091c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2092c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2093c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2094c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2095cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 209620128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian mVisibleRegionsDirty = true; 209720128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian repaintEverything(); 2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { 2101c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this); 2102c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (!hw->isScreenAcquired()) { 2103c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously released"); 2104c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2105c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2106c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2107c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden hw->releaseScreen(); 2108c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 2109c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 2110c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2111cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2112cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2113cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2114c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2115c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2116c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().release(type); 2117b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2118c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mVisibleRegionsDirty = true; 2119c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // from this point on, SF will stop drawing on this display 2120b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2121b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2122c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::unblank(const sp<IBinder>& display) { 2123b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 2124db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2125db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2126b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2127db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenAcquired(SurfaceFlinger& flinger, 2128db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2129b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2131db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2132db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to unblank null display %p", mDisplay.get()); 2133db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2134db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to unblank virtual display"); 2135db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2136db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenAcquired(hw); 2137db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2138b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2139b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2140b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2141db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(*this, display); 2142db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2145c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::blank(const sp<IBinder>& display) { 2146b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 2147db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2148db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2149b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2150db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenReleased(SurfaceFlinger& flinger, 2151db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2152b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2153db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2154db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2155db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to blank null display %p", mDisplay.get()); 2156db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2157db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to blank virtual display"); 2158db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2159db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenReleased(hw); 2160db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2161b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2162b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2163b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2164db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(*this, display); 2165db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2166b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2167b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2168b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2169b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21721d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 2173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 2174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 217599b49840d309727678b77403d6cc9f920111623fMathias Agopian 217699b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 2177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 2178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 21839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 21849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 21859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 21869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 21879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 21889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 21899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 21909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 21919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 21928b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 21939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 21949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 21959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 21969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 21979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 219882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 219982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 220025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 220125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 220225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 220325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 220425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 220525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 220635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 220725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 220825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 220925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 221025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 221182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 221282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 221335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 221482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 221525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 221625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 221725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 221825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 221925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 222035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 222125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 222482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 222582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 222682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 222748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 222882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 222982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 223048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 223182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 223282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 223382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 223482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 223548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 223625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 223725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 223825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 223925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 224025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 224125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 224225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 224325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 224425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 224525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 224625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 224725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 224882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 224982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 225082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 225182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 225282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 225382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 225482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 225582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 225648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 225782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 225882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 225982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 226082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 226182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 226282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 226382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 226482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 226582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 226682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 226782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 226882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 226982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2270ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 227125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 227225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 227325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 227425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 227525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 227625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 227725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 227825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 227925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 228025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 228125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 228225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 228325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 228425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 228525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 228625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 228725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 228825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 228925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 22904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 22914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 22924803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 22934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 22944803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NO_RGBX_8888 22954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NO_RGBX_8888" 22964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 22974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 22984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 22994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23004803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 23014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 23024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 23044803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 23054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23064803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 23074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 23084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 23094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 231082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 231182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 231282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 231382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 231482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 231582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 231682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 231782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 231882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2319bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 232082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23214803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 23224803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 23234803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 23244803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 23254803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 23264803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 23274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 23284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 23294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 233082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 233182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 233282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 233382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 233482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 233582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 233682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 233782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 233882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 233982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2340bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 234182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 234282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 234382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 2344ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 234582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 234682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 234782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 234882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 234982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 235082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 235182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 23521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23545f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 23555f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 23565f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23578dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size()); 23588dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden result.append(buffer); 23595f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 23605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 23611d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian hw->dump(result, buffer, SIZE); 23625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 23635f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23645f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 236582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 236682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 23671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 236882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 236982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 23701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2371888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 23724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 237382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 237482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 237582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 237682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 237782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 237882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 2379d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 238082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 2381d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID)); 238282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 238373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 238482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 238582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 23869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 23874297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 238882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 238982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 23904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getOrientation(), hw->canDraw()); 239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 239282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 239482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2395c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 239682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 239782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 23988b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian " y-dpi : %f\n", 239982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 240082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2401c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2402b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2403b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2404b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiY(HWC_DISPLAY_PRIMARY)); 240582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 240682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 240782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 240882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 240982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 241082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 241182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 241282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 241382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 241482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 241582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 241782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 241882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 241982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 242182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 242282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 242482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 242682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 2429cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian hwc.dump(result, buffer, SIZE); 243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 243182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 243282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 243382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 243482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 243582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2438cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopianconst Vector< sp<LayerBase> >& 2439cb55857bbde34a06c19dde3db5064d1717a0173eMathias AgopianSurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) { 2440db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 2441cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ(); 2442cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2443cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 244463f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 244563f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 244663f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 244763f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 244863f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 244963f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 245063f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 245163f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 245263f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 245363f165fd6b86d04be94d4023e845e98560504a96Keun young Park (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start"); 245463f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 245563f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 245663f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 245763f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 245863f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 245963f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 246063f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 246163f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 24698e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 24708e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2475a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 247699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 247799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2478e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2479375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2480375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 249099b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 249199b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2492e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2502b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 250399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2504375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2505375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2506375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2507e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2508375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 251301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 251435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 251953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 252053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 252353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2524cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2526cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2531cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25334d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 25344d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 25354d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 25364d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 253753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 253853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 253953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 254053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 254153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 254253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2543a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2544a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2545a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2546a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2547a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2548a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 255001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2553b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 255412839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 25584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 25594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 256753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 256887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 256999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 257053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 257153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 257259119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 257359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 25743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack, 2575118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2576118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2577118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 25783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut); 2579118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2580118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 25813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack, 25829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 258359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 258422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 258522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 258659119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 258759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 258859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 258959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 25903ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian // FIXME: figure out what it means to have a screenshot texture w/ multi-display 25913ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 25924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 25934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 259459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 259559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 259659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 259759119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 259859119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 259959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 260059119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 260159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 260259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 260359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2604a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2605a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 26069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 26079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 260859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2609015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 261059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 261159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 26129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 26139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 261459119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 261559119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 261659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 261759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 261859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 26199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 26209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 262159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2622bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian DisplayDevice::setViewportAndProjection(hw); 2623bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian 26249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2625c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2626c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 26279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 26289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2629a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2630a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 26314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 26329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 26339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 26349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 2635fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian layer->draw(hw); 26369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 263759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2639118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 26409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 26419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 26429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 264359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 26459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 26469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 26479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 26489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 264959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 26519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 26529d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display, 265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2655bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2656bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2658fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2659fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 26643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 26673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 26684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 26694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 267074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 26724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getSecureLayerVisible()) { 2673ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 26743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 26753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 26763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 26773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 2678ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h); 267974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 26803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 268174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 268274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 268374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 268474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 2685fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian const bool filtering = sw != hw_w || sh != hw_h; 268674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2687ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2688ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// sw, sh, minLayerZ, maxLayerZ); 2689c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 269074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 269174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 269274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 269374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 269474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 269574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 269774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2698fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 269974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 270074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 270174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 270274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 270374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 270474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2705c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 270674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 270774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 270874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 2709135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian GLint viewport[4]; 2710135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian glGetIntegerv(GL_VIEWPORT, viewport); 271174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 271274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 271374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 271474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2715ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 271674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 271774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 271874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 271974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 272074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2721f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 27223ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 27239575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 272474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 272574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 27263ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const uint32_t z = layer->drawingState().z; 27273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 27283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(true); 27293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer->draw(hw); 27303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(false); 2731bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 273274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 273374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 273474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 273574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 273674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 273774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 273874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 273974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 274074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 274174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 274274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 274374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 27447b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian if (ptr != MAP_FAILED) { 274574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2746fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 274774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 274874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 274974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 275074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 275174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 275274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 275374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 275474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 275574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 275674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 275774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 275874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 2759135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); 276074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 276174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 276274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 276374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 276474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 276574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 276674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 276774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 276874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 276974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 277074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2771e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 27724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2773e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2774ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2775c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 277674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 277774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 277874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 277974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 27809d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 27811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 278274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2783bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2784bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 27869d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown if (CC_UNLIKELY(display == 0)) 27871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 27881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 27901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 27911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 27931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 27949d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown sp<IBinder> display; 27951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 27961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 27971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 27981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 279974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 280074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2801bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2802bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 28031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 28041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 28059d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display, 280674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2807bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2808bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 28099d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown : flinger(flinger), display(display), 2810bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2811bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2812bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 28131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 28141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 28161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 28171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 28191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 28209d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown result = flinger->captureScreenImplLocked(display, 2821bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 28221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 28231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 28251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 28261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 28279d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 28281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 28291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 28301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 28311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 28331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 28341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 28351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 28361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2837921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2838921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2839921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2840921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2841921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2842921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2843921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2844921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2845921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2847be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 2848921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2849921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2850be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2851be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t ls = l->currentState().layerStack; 2852be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t rs = r->currentState().layerStack; 2853be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 2854be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 2855be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2856921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2857921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2858be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 2859be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 2860be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2861be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 2862921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2863921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2864921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2865921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 28663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 28673ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(DisplayDevice::DISPLAY_ID_INVALID) { 2868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 28703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 28713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(type), layerStack(0), orientation(0) { 2872da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 2873da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 2874b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 28757303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2876b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 287796f0819f81293076e652792794a961543e6750d7Mathias Agopian 2878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2879