SurfaceFlinger.cpp revision 2adaf04fab35cf47c824d74d901b54094e01ccd3
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> 43392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 48d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 49cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 531c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 55921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 590f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 60db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 61d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 621f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 65118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 68a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.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 194692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 195692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 196692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 197692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 198692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 199692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 200692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 201692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 202692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 203692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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 } 209692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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 475692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall Mutex::Autolock _l(mStateLock); 476692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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; 501692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked(type); 502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 503692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 504f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); 505f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<SurfaceTextureClient> stc = new SurfaceTextureClient( 5062adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden static_cast< sp<IGraphicBufferProducer> >(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( 5742adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 575134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 5762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden sp<IBinder> surfaceTextureBinder(bufferProducer->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 5932adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // GLConsumer 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) { 615692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 6161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 617692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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); 755692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 756692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 7579e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 758692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 759692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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( 11752adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden static_cast< sp<IGraphicBufferProducer> >( 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, 1186692c723e84e6f2747447d871d468ff50e5c73f19Jesse 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) { 1523da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 1524a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 152552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // set the frame buffer 152652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glMatrixMode(GL_MODELVIEW); 152752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glLoadIdentity(); 1528a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1529a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 153085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1531e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1532b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1533b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1534b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1535b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1536b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1537b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1538b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1540766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1541766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1542766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1543766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1544766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1545766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1546766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1547766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1548766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1549766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1550766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1551766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1552766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1553766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1554b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 155587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1556b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 155755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1558b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1559a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1560f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1561766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1562766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1563f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1564f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1565f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1566766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1567f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1568f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1569f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1570f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 1571f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const GLint height = hw->getHeight(); 1572f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glScissor(scissor.left, height - scissor.bottom, 1573f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian scissor.getWidth(), scissor.getHeight()); 1574f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 1575f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glEnable(GL_SCISSOR_TEST); 1576f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1577f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 157885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 15794b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 158085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 158185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 158285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 15834b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 158485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 158585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 158685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 158785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 158885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 158985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 1590a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 15914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 159285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 159385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 159485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 159585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 159685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 159785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && layer->isOpaque() 159885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1599cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1600cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1601cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1602cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 160385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 160485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 160585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1606cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 160785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1608a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1609da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1610da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1611da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 1612da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i); 1613da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1614da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1615cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1616a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 161785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 161885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 161985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 162085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 162185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 162285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 162385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 162485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 162585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 162685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 162785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 16284b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 16294b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1630f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1631f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 1632f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian glDisable(GL_SCISSOR_TEST); 1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, 163655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const Region& region) const 1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1638f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1639b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1640f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1641b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1642f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 164355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 1644f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1645f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1646f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1647f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 164855801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian GLfloat vertices[][2] = { 164955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.top }, 165055801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.left, height - r.bottom }, 165155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.bottom }, 165255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian { r.right, height - r.top } 165355801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian }; 165455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1655f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1656f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165996f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 166096f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 16611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 166296f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 16634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 16644f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 166596f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1666921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1667921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 166896f0819f81293076e652792794a961543e6750d7Mathias Agopian 16694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 167096f0819f81293076e652792794a961543e6750d7Mathias Agopian} 167196f0819f81293076e652792794a961543e6750d7Mathias Agopian 167296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 167396f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 167496f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 167596f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 167696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 16773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian setTransactionFlags(eTransactionNeeded); 167896f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1681076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1685076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 16929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 169376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 169476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 16959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 169676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 169776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 169876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 16998c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 17002f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 17010b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 17023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 17033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 170496f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 170596f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 17069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 17079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 17089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1709dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1710dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1711dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1712dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1713dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1719bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 172399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17288b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 17298b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 17308b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 17318b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 17328b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 17337c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 1734698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 173528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1736e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 17372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 17392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 17402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 17417c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 17422d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 17432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 17447c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 17457c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 17467c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 17472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 17482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 17492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 1753e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1755e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1756e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1757b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1758b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1759e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1760698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1761698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1762d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 1763d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 1764d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 1765d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 1766d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 1767d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 1768d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 1769d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 1770d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<IBinder> binder = s.client->asBinder(); 1771d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 1772d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 1773d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 1774d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1775d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 1776d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1777d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1778d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1779698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1780386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 178128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1782386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 178328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1784698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1785386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1786386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1787386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 17882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 17892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17912d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 1792386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 17932d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 1794386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1795386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1796386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1797386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 17982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 17992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 1800386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1801386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1802cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 18089a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 18099a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 18109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 18119a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 1812e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 18139a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 18143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 1815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 182800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 1829e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1833e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1834e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 1847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 1849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1852e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 1855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 1856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 1859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 1862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 1870e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 1871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eVisibilityChanged) { 1887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1909921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 19100ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 19110ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 19120ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 19133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian uint32_t w, uint32_t h, PixelFormat format, 1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1916076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1917a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 19186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 19196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1920921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 19216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 19226e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 19236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 19248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1925921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 19263165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 19273165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 19283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createNormalLayer(client, w, h, flags, format); 1929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 19303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceBlur: 19313165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 19323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createDimLayer(client, w, h, flags); 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 19343165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceScreenshot: 19353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer = createScreenshotLayer(client, w, h, flags); 1936118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1939076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 194096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1941285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 194296f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 19448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 194596f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1946a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 19471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 194896f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1954921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 19553ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 195696f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 19571c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 196092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1966a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1967a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1968a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 19698f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1970a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1974a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1975a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1976a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1977a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1978a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 19793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<Layer> layer = new Layer(this, client); 1980f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 198199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1982921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1983076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1988921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 19893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 199096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19923ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerDim> layer = new LayerDim(this, client); 1993118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1994118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1995118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1996921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 19973ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const sp<Client>& client, 1998118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1999118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 20003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, client); 2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2004921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 20059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 20069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 20079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 20089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 20098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 20100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 20110aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 20120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 20139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 20149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 201548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 20160aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 201796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 2018b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 201948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 202048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 202148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 202213233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian setTransactionFlags(eTransactionNeeded); 202348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 20249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 20259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 20269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 20279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 2028921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 2029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2030759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 2031ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 2032ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 2033ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 2034ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 2035ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 2036ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 2037ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 2038ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 2039ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 2040ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 2041e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 2042ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 2043f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 2044e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2045ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2046ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2047ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2050b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2051b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 205213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 205313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // reset screen orientation 205413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 205513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 205613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 205700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian d.what = DisplayState::eDisplayProjectionChanged; 2058692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 205913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 20604c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 20614c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 206213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 206313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 2064cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian onScreenAcquired(getDefaultDisplayDevice()); 206513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 206613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 206713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 206813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 206913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 207013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 207113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 207213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 207313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 207413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 207513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 207613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 207713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 207813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 207913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 208013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 208113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 2082cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { 2083c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this); 2084c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (hw->isScreenAcquired()) { 2085c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // this is expected, e.g. when power manager wakes up during boot 2086c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously acquired"); 2087c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2088c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2089c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 20904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->acquireScreen(); 2091c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 2092c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 2093c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2094c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().acquire(type); 2095c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2096c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2097c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2098c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2099c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 210120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian mVisibleRegionsDirty = true; 210220128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian repaintEverything(); 2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2105cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { 2106c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this); 2107c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (!hw->isScreenAcquired()) { 2108c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously released"); 2109c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2110c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2111c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2112c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden hw->releaseScreen(); 2113c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 2114c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 2115c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2116cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2117cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2118cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2119c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2120c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2121c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().release(type); 2122b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2123c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mVisibleRegionsDirty = true; 2124c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // from this point on, SF will stop drawing on this display 2125b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2126b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2127c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::unblank(const sp<IBinder>& display) { 2128b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 2129db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2131b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2132db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenAcquired(SurfaceFlinger& flinger, 2133db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2134b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2135db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2136db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2137db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to unblank null display %p", mDisplay.get()); 2138db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2139db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to unblank virtual display"); 2140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2141db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenAcquired(hw); 2142db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2143b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2144b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2145b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2146db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(*this, display); 2147db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2150c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::blank(const sp<IBinder>& display) { 2151b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 2152db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2153db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2154b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2155db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenReleased(SurfaceFlinger& flinger, 2156db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2157b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2158db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2159db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2160db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to blank null display %p", mDisplay.get()); 2161db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2162db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to blank virtual display"); 2163db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2164db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenReleased(hw); 2165db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2166b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2167b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2168b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2169db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(*this, display); 2170db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2171b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2172b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2173b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2174b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21771d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 2178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 218099b49840d309727678b77403d6cc9f920111623fMathias Agopian 218199b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 2183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 21889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 21899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 21909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 21919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 21929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 21939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 21949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 21959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 21969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 21978b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 21989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 21999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 22009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 22019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 22029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 220382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 220482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 220525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 220625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 220725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 220825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 220925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 221025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 221135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 221225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 221325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 221425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 221525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 221682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 221782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 221835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 221982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 222025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 222125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 222225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 222325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 222425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 222535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 222625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 222982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 223082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 223182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 223248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 223382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 223482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 223548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 223682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 223782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 223882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 223982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 224048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 224125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 224225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 224325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 224425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 224525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 224625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 224725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 224825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 224925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 225025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 225125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 225225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 225382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 225482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 225582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 225682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 225782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 225882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 225982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 226082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 226148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 226282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 226382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 226482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 226582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 226682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 226782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 226882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 226982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 227082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 227182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 227282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 227382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 227482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2275ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 227625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 227725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 227825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 227925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 228025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 228125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 228225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 228325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 228425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 228525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 228625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 228725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 228825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 228925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 229025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 229125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 229225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 229325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 229425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 22954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 22964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 22974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 22984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 22994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NO_RGBX_8888 23004803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NO_RGBX_8888" 23014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 23034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 23044803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 23064803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 23074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 23094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 23104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 23124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 23134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 23144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 231582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 231682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 231782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 231882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 231982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 232082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 232182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 232282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 232382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2324bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 232582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23264803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 23274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 23284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 23294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 23304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 23314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 23324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 23334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 23344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 233582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 233682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 233782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 233882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 233982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 234082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 234182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 234282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 234382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 234482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2345bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 234682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 234782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 234882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 2349ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 235082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 235182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 235282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 235482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 235582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 235682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 23571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 235882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23595f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 23605f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 23615f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23628dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size()); 23638dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden result.append(buffer); 23645f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 23655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 23661d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian hw->dump(result, buffer, SIZE); 23675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 23685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 237082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 237182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 23721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 237382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 237482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 23751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2376888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 23774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 237882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 237982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 238082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 238182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 238282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 238382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 2384d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 238582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 2386d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID)); 238782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 238873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 238982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 239082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 23919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 23924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 239482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 23954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getOrientation(), hw->canDraw()); 239682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 239782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 239882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 239982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2400c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 240182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 240282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 24038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian " y-dpi : %f\n", 240482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 240582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2406c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2407b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2408b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2409b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiY(HWC_DISPLAY_PRIMARY)); 241082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 241182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 241282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 241382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 241482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 241582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 241782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 241882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 241982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 242182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 242282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 242482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 242682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 242982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 243182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 243282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 243382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 2434cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian hwc.dump(result, buffer, SIZE); 243582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 243682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 243782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 243882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 243982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2443cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopianconst Vector< sp<LayerBase> >& 2444cb55857bbde34a06c19dde3db5064d1717a0173eMathias AgopianSurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) { 2445db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 2446cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ(); 2447cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2448cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 244963f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 245063f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 245163f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 245263f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 245363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 245463f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 245563f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 245663f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 245763f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 245863f165fd6b86d04be94d4023e845e98560504a96Keun young Park (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start"); 245963f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 246063f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 246163f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 246263f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 246363f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 246463f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 246563f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 246663f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 24748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 24758e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 2476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2480a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 248199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 248299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2483e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2484375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2485375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 24901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 24911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 249599b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 249699b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2497e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2507b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 250899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2509375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2510375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2511375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2512e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2513375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 251801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 251935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 252453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 252553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 252853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2529cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2530cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2531cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2536cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25384d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 25394d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 25404d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 25414d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 254253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 254353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 254453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 254553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 254653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 254753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2548a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2549a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2550a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2551a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2552a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2553a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 255501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2558b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 255912839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 25634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 25644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 257387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 257499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 257553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 257653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 257759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 257859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 25793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack, 2580118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2581118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2582118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 25833ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut); 2584118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2585118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 25863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack, 25879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 258859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 258922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 259022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 259159119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 259259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 259359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 259459119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 25953ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian // FIXME: figure out what it means to have a screenshot texture w/ multi-display 25963ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 25974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 25984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 259959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 260059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 260159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 260259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 260359119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 260459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 260559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 260659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 260759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 260859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2609a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2610a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 26119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 26129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 261359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2614015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 261559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 261659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 26179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 26189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 261959119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 262059119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 262159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 262259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 262359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 26249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 26259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 262659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2627bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian DisplayDevice::setViewportAndProjection(hw); 2628bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian 26299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2630c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2631c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 26329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 26339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2634a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2635a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 26364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 26379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 26389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 26399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 2640fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian layer->draw(hw); 26419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 264259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2644118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 26459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 26469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 26479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 264859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 26509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 26519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 26529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 26539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 265459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 26569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 26579d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display, 265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2660bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2661bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2663fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2664fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 26693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 267074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 26723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 26734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 26744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 26774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getSecureLayerVisible()) { 2678ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 26793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 26803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 26813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 26823b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 2683ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h); 268474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 26853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 268674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 268774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 268874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 268974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 2690fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian const bool filtering = sw != hw_w || sh != hw_h; 269174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2692ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2693ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// sw, sh, minLayerZ, maxLayerZ); 2694c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 269574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 269774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 269874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 269974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 270074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 270174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 270274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2703fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 270474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 270574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 270674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 270774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 270874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 270974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2710c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 271174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 271274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 271374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 2714135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian GLint viewport[4]; 2715135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian glGetIntegerv(GL_VIEWPORT, viewport); 271674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 271774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 271874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 271974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2720ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 272174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 272274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 272374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 272474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 272574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2726f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 27273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 27289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 272974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 273074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 27313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const uint32_t z = layer->drawingState().z; 27323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 27333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(true); 27343ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian layer->draw(hw); 27353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (filtering) layer->setFiltering(false); 2736bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 273774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 273874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 273974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 274074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 274174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 274274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 274374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 274474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 274574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 274674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 274774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 274874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 27497b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian if (ptr != MAP_FAILED) { 275074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2751fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 275274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 275374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 275474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 275574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 275674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 275774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 275874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 275974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 276074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 276174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 276274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 276374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 2764135e5899f70a67e62baaf6dbec7ba2ce611ca16aMathias Agopian glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); 276574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 276674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 276774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 276874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 276974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 277074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 277174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 277274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 277374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 277474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 277574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2776e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 27774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2778e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2779ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2780c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 278174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 278274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 278374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 278474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 27859d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 27861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 278774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2788bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2789bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 27919d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown if (CC_UNLIKELY(display == 0)) 27921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 27931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 27951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 27961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 27981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 27999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown sp<IBinder> display; 28001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 28011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 28021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 28031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 280474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 280574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2806bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2807bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 28081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 28091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 28109d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display, 281174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2812bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2813bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 28149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown : flinger(flinger), display(display), 2815bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2816bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2817bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 28181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 28191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 28211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 28221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 28241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 28259d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown result = flinger->captureScreenImplLocked(display, 2826bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 28271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 28281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 28301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 28311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 28329d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 28331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 28341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 28351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 28361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 28381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 28391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 28401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 28411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2842921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2843921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2844921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2845921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2846921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2847921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2848921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2849921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2850921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2852be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 2853921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2854921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2855be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2856be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t ls = l->currentState().layerStack; 2857be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t rs = r->currentState().layerStack; 2858be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 2859be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 2860be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2861921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2862921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2863be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 2864be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 2865be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2866be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 2867921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2868921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2869921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2870921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 28713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 28723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(DisplayDevice::DISPLAY_ID_INVALID) { 2873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 28753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 28763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(type), layerStack(0), orientation(0) { 2877da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 2878da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 2879b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 28807303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2881b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 288296f0819f81293076e652792794a961543e6750d7Mathias Agopian 2883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2884