SurfaceFlinger.cpp revision cd60f99aba9e750700a967db30b74a29145739cf
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> 23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h> 41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8099b49840d309727678b77403d6cc9f920111623fMathias Agopian 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 985f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mBootFinished(false) 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 100a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 114c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 131a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 1428b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian Vector<DisplayState> displays; 1438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian DisplayState d; 144818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian d.what = DisplayState::eOrientationChanged; 145ea599dfff03b45903dae3288274c31cb24fd483fJesse Hall d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN]; 1463165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian d.orientation = DisplayState::eOrientationDefault; 1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian displays.add(d); 1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian setTransactionState(state, displays, 0); 14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 151a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1547e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 15796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 15896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 15996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16096f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::createDisplay() 166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayDeviceState info(intptr_t(token.get())); // FIXME: we shouldn't use the address for the id 185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 189e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 190e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 191e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) { 192e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 193e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 194e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 195e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return mDefaultDisplays[id]; 196e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 197e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 203b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 208a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2093330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 215921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 219a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 220a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 221a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 224921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 225921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 226921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian GLuint texture; 227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageDestroyGLTexture(GLuint texture) 229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : texture(texture) { 230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 231921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian glDeleteTextures(1, &texture); 233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 236921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(texture)); 237921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 238921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat( 240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian PixelFormat format, 243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian for (int i=0 ; i<n ; i++) { 251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint nativeVisualId = 0; 252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); 253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (nativeVisualId>0 && format == nativeVisualId) { 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian *outConfig = configs[i]; 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint attribs[] = { 270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_RECORDABLE_ANDROID, EGL_TRUE, 272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE 273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (err) { 276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // maybe we failed because of EGL_RECORDABLE_ANDROID 277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); 278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian attribs[2] = EGL_NONE; 279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); 282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { 283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 288a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 294a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 298a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) { 305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext); 306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!result) { 307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Couldn't create a working GLES context. check logs. exiting..."); 308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 315a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 316a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 317a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 318a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 319a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 3208b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 321a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint w, h; 322a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_WIDTH, &w); 323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_HEIGHT, &h); 3248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 325a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 326a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 3277303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 3298b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3419575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 3429575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 3439575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 3449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3469575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3479575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 3499575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 354ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 355ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize EGL 38434a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 38534a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Initialize the main display 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create native window to main display 3891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis sp<FramebufferSurface> fbs = FramebufferSurface::create(); 3901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis if (fbs == NULL) { 391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Display subsystem failed to initialize. check logs. exiting..."); 392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceTextureClient> stc(new SurfaceTextureClient( 396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue()))); 3971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis 398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian int format; 4001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis ANativeWindow* const anw = stc.get(); 4011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis anw->query(anw, NATIVE_WINDOW_FORMAT, &format); 40234a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLConfig = selectEGLConfig(mEGLDisplay, format); 40334a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); 404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize our main display hardware 406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) { 408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mDefaultDisplays[i] = new BBinder(); 409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i)); 410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig); 413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mDisplays.add(hw->getDisplayId(), hw); 414a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 415a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 4164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian EGLSurface surface = hw->getEGLSurface(); 41734a09ba1efd706323a15633da5044b352988eb5fJesse Hall initializeGL(mEGLDisplay, surface); 418d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 419028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 420028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventThread = new EventThread(this); 421028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventQueue.setEventThread(mEventThread); 422028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 4238630320433bd15aca239522e54e711ef6372ab07Mathias Agopian // initialize the H/W composer 4248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian mHwc = new HWComposer(this, 4258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian *static_cast<HWComposer::EventHandler *>(this), 4268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian fbs->getFbHal()); 42792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 42892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 42992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4308630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 431a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 432d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 433d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 434a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 435a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 4368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 440a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 441a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 442a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 443a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 444a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 445a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 446a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 447a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 448a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 452a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 456d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 457582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 458582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 461134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 462134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 469582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 470582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 471582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 472582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 477582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 479134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 480134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 481134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 487582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 488582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 489582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 490582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 491582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 492134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 493134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 495134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 496134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 498c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) { 4991e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian // TODO: this is here only for compatibility -- should go away eventually. 5001e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian if (uint32_t(dpy) >= 1) { 501c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian return BAD_INDEX; 502c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian const HWComposer& hwc(getHwComposer()); 5058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian float xdpi = hwc.getDpiX(); 5068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian float ydpi = hwc.getDpiY(); 5078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // The density of the device is provided by a build property 5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian float density = Density::getBuildDensity() / 160.0f; 5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (density == 0) { 5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // the build doesn't provide a density -- this is wrong! 5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // use xdpi instead 5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian ALOGE("ro.sf.lcd_density must be defined as a build property"); 5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = xdpi / 160.0f; 5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (Density::getEmuDensity()) { 5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // if "qemu.sf.lcd_density" is specified, it overrides everything 5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian xdpi = ydpi = density = Density::getEmuDensity(); 5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density /= 160.0f; 5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian info->w = hw->getWidth(); 5404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian info->h = hw->getHeight(); 5418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->xdpi = xdpi; 5428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->ydpi = ydpi; 5438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->fps = float(1e9 / hwc.getRefreshPeriod()); 5448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->density = density; 5454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian info->orientation = hw->getOrientation(); 546888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian // TODO: this needs to go away (currently needed only by webkit) 5474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo); 548888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 549c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 550c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 551d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 552d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 553d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 5548aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 555bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 556bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 5575f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> surface) { 5583094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5595f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian sp<IBinder> token; 5603094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 5613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5625f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian token = mExtDisplayToken; 5633094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5655f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian if (token == 0) { 5665f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian token = createDisplay(); 5673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5695f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian { // scope for the lock 5705f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian Mutex::Autolock _l(mStateLock); 5715f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian if (surface == 0) { 5725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // release our current display. we're guarantee to have 5735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // a reference to it (token), while we hold the lock 5745f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mExtDisplayToken = 0; 5755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } else { 5765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian mExtDisplayToken = token; 5775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 5785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 5795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian DisplayDeviceState& info(mCurrentState.displays.editValueFor(token)); 5805f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian info.surface = surface; 5815f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 5825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 5833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 58699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 58999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 59199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 60899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 60999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 61099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 61199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 61299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 61499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 61599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 61999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 62099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6228630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) { 6238630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mEventThread->onVSyncReceived(dpy, timestamp); 6248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 6258630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 6268630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) { 6278630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().eventControl(event, enabled); 6288630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 6298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 6304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 6311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 63299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 6334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 6344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 6384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 645e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 64787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 652cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 65387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 6553a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 657cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 658cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 659cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 660cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 662cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 663cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 664cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 665cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 666cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 667cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 668cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 669cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 670cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 671cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 672cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 673cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 674cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 675cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 676cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 677cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 678cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 679cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 681cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 682cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 683cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 684cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_TEXTURE_2D); 685cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDisable(GL_BLEND); 686cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glColor4f(1, 0, 1, 1); 687cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 688cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator it = dirtyRegion.begin(); 689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian Region::const_iterator const end = dirtyRegion.end(); 690cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian while (it != end) { 691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Rect& r = *it++; 692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian GLfloat vertices[][2] = { 693cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.top }, 694cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.left, height - r.bottom }, 695cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.bottom }, 696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian { r.right, height - r.top } 697cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian }; 698cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 701cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 702cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // FIXME 703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) { 704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian eglSwapBuffers(mEGLDisplay, hw->getEGLSurface()); 705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 708cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 709cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 710cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 712cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 713cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 714cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 716cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 717cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 718cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 719cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 721cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 722cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers[i]->onPreComposition()) { 724cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 725cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 726cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 727cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 729cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 730cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 731a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 733cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 734cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 735cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const size_t count = currentLayers.size(); 736cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian currentLayers[i]->onPostComposition(); 738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 74352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 74587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 74687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 74787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 74892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 7494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 75087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region opaqueRegion; 75187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion; 75287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian computeVisibleRegions(currentLayers, 7534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 7544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 75587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 75687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 75787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const size_t count = currentLayers.size(); 75887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian for (size_t i=0 ; i<count ; i++) { 75987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Layer::State& s(currentLayers[i]->drawingState()); 7604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 76187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!currentLayers[i]->visibleRegion.isEmpty()) { 76287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian layersSortedByZ.add(currentLayers[i]); 76387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 76487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 7653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 7664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 7674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.set(hw->getBounds()); 768cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->undefinedRegion.subtractSelf( 769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getTransform().transform(opaqueRegion)); 7703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 7713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 7733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 77552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 77652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 77752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 77852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool workListsDirty = mHwWorkListDirty; 77952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mHwWorkListDirty = false; 78092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 7814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 782cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Vector< sp<LayerBase> >& currentLayers( 783cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 78452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 785303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 7861e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const int32_t id = hw->getDisplayId(); 7871e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian if (hwc.createWorkList(id, count) >= 0) { 7881e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 7891e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 7901e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 7911e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 7921e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian 7931e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian if (CC_UNLIKELY(workListsDirty)) { 7941e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian layer->setGeometry(hw, *cur); 7951e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 7961e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian cur->setSkip(true); 7971e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 79852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 79952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 8001e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian /* 8011e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian * update the per-frame h/w composer data for each layer 8021e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian * and build the transparent region of the FB 8031e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian */ 8041e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian layer->setPerFrameData(hw, *cur); 8051e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 80652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 80787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 80852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 80952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 81052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 811cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 81252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 81552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 81692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 8174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 819cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 820cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 821cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 82252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // repaint the framebuffer (if needed) 823cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDisplayComposition(hw, dirtyRegion); 82452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 82887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 82952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 8304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 8314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 83252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 837841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 838b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 839a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 840a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 841c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 84252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 843ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 84452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // FIXME: eventually commit() won't take arguments 8455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // FIXME: EGL spec says: 8465f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // "surface must be bound to the calling thread's current context, 8475f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian // for the current rendering API." 848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian DisplayDevice::makeCurrent( 849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext); 8504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface()); 85152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 85252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 85392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 8544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 8554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ()); 85652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 85752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 8581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian int32_t id = hw->getDisplayId(); 8591e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 8601e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 86152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 862d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 86352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 86552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 866d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 86752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 868ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 869e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 870e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 871a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 872a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 87587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 877841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 878841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 879ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 880ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 881ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 882ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 883ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 884ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 885ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 886ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 887ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 888ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 89087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 891ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 892ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 893ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 895ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 8963d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 89887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 8993d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 9003d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 910076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 9213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 92592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 92692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 92792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 928e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 929e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 93092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 93292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 93392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t dc = draw.size(); 93492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 93592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 93692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 93792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 93892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 93992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 940e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 941e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 94292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 94392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) { 94492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDisplays.removeItem(draw[i].id); 94592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 94692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 94792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 94892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 94992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 950e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 951111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 952e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 953e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // recreating the DisplayDevice 954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceTextureClient> stc( 956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian new SurfaceTextureClient(state.surface)); 957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<DisplayDevice> disp = new DisplayDevice(this, 959e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian state.id, stc, 0, mEGLConfig); 960e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 961e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp->setLayerStack(state.layerStack); 962e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp->setOrientation(state.orientation); 963e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // TODO: take viewport and frame into account 964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mDisplays.replaceValueFor(state.id, disp); 965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 96692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (state.layerStack != draw[i].layerStack) { 9674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& disp(getDisplayDevice(state.id)); 96828947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian disp->setLayerStack(state.layerStack); 96992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 970e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (state.orientation != draw[i].orientation || 971e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian state.viewport != draw[i].viewport || 972e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian state.frame != draw[i].frame) { 9734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& disp(getDisplayDevice(state.id)); 9744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian disp->setOrientation(state.orientation); 975e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // TODO: take viewport and frame into account 97692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 97792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 97892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 97992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 98092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 98192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 98292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 984e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 985e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceTextureClient> stc( 986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian new SurfaceTextureClient(state.surface)); 987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<DisplayDevice> disp = new DisplayDevice(this, state.id, 988e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian stc, 0, mEGLConfig); 989e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mDisplays.add(state.id, disp); 99092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 99192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 9933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 9963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 9973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 999cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 1000cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (currentLayers.size() > previousLayers.size()) { 10013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 10023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 10033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 10043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 10053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 10063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 10073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 10083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 10093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 10103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const size_t count = previousLayers.size(); 10113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 10133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 10143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 10153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 10163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 10173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 10183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian Layer::State front(layer->drawingState()); 10193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian Region visibleReg = front.transform.transform( 10203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian Region(Rect(front.active.w, front.active.h))); 10213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian invalidateLayerStack(front.layerStack, visibleReg); 10220aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 10274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 10284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 10294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 10304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 10314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 10324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 10334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 10344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 10354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 10394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 10404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransationPending = false; 10414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 104587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 104687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1048841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1049841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 1058076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 1061970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian // only consider the layers on the given later stack 106487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 106587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 106687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1067ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1068ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1069ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1071ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1072ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1073ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1074ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1075ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1076ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1077ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1079ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1080ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1081ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1082ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1083ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1085ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1086ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1087ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 10883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) { 1089a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 10904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1092ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1093ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1094ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region transparentRegionScreen; 10964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 10974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 10984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 10994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 11004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = tr.transform(s.transparentRegion); 11014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 11024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 11034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 11044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen.clear(); 11054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 11074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = s.transparentRegion; 11084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian visibleRegion.subtractSelf(transparentRegionScreen); 1110ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1112ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 11134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1114ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1115ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1116ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1117ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1118ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1122ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1123ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1124ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1125ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1126ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1127ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1139a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1140ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1141ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1143ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1144ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1145ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1146ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1147ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1148ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1149ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1150a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1151ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 11524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 11534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1154ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1155ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 116087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 11648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 117487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 117592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 11774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 11784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 117992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 118092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 118187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 118287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 118387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 118699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 11874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 1188cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 11894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 11904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 1191cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 119287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 119387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Layer::State s(layer->drawingState()); 119487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 11954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11964da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 11973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1200ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1201ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1202ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1203ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1204ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 120599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 120787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 120987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 121087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1211b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 12124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 12150f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 121629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 121729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 121829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 12194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 12210f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 122229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1223df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 122495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 12250f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 12264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 122829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 12294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 12304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1234cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, dirtyRegion); 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1236cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // FIXME: we need to call eglSwapBuffers() on displays that have 1237cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // GL composition and only on those. 1238cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // however, currently hwc.commit() already does that for the main 1239cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // display and never for the other ones 1240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) { 1241cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // FIXME: EGL spec says: 1242cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // "surface must be bound to the calling thread's current context, 1243cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // for the current rendering API." 1244cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian eglSwapBuffers(mEGLDisplay, hw->getEGLSurface()); 1245d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 1246d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 12479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 12484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1251cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 12538630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 12541e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian int32_t id = hw->getDisplayId(); 12551e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 12561e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1257a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 12581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER); 125952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (cur==end || fbLayerCount) { 1260a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 12610f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian DisplayDevice::makeCurrent(hw, mEGLContext); 1262a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 126352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // set the frame buffer 126452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glMatrixMode(GL_MODELVIEW); 126552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian glLoadIdentity(); 1266a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1267a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 12681e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian if (hwc.getLayerCount(id, HWC_OVERLAY)) { 1269b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1270b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1271b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1272b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1273b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1274b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1275b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1276b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 12774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Region region(hw->undefinedRegion.intersect(dirty)); 1278b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 127987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1280b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 128187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian drawWormhole(region); 1282b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1283a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 12844b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1285a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 1286a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 1287a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 12884b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 12894297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 1290a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 12914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Transform& tr = hw->getTransform(); 1292a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall for (size_t i=0 ; i<count ; ++i) { 1293a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 12944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 1295cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (cur != end) { 1296cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // we're using h/w composer 1297cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!clip.isEmpty()) { 1298cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (cur->getCompositionType() == HWC_OVERLAY) { 1299cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1300cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian && layer->isOpaque()) { 1301cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1302cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1303cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1304cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1305cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 1306cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 1307a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1308cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->setAcquireFence(hw, *cur); 1309a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1310a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall ++cur; 1311cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 1312cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // we're not using h/w composer 1313cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!clip.isEmpty()) { 1314cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 1315cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1316a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 13174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 13184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 132187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::drawWormhole(const Region& region) const 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1323f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1324b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1325f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1326b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1327f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1328f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1329f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1330f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1331f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1332f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1333f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1334f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1335f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1336f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1337f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1338f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1339f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1340f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1341f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1342f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1343f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134696f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 134796f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 13481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 134996f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 13504f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 13514f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 135296f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1353921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1354921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 135596f0819f81293076e652792794a961543e6750d7Mathias Agopian 13564f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 135796f0819f81293076e652792794a961543e6750d7Mathias Agopian} 135896f0819f81293076e652792794a961543e6750d7Mathias Agopian 135996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 136096f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 136196f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 136296f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 136396f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 13643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian setTransactionFlags(eTransactionNeeded); 136596f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1368076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 13799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 138076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 138176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 138376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 138476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 138576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 13868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 13872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 13880b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 13893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 13903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 139196f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 139296f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 13939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 13949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1396dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1397dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1398dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1399dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1400dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1406bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 141099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14158b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 14168b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 14178b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 14188b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 14198b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 142128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1427b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1428b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 143328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1435386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 143628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1437386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 143828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1440386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1441386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1442386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1443386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1444386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1445386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1446386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1447386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1448386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1449386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 145032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1451386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1452386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1453386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1454cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1461e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token)); 1462e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.id >= 0) { 1463e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1464e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1466e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1476818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian if (what & DisplayState::eOrientationChanged) { 1477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1480e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1481818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian } 1482818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian if (what & DisplayState::eFrameChanged) { 1483e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1484e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1485e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1486e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1487818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian } 1488818b46058aa3006e1d3c178abd36d4f10823f5d9Mathias Agopian if (what & DisplayState::eViewportChanged) { 1489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 1503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 1505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 1507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 1508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 1514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 1522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 1527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 1535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eVisibilityChanged) { 1539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1542e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 1543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 1544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 1547e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 1550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1556e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1557e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1558e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1559e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1560e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1561921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 15620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 15630ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 15640ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 15706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 15716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1572921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 15736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 15746e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 15756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 15768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1577921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 15783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 15793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 1580921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createNormalLayer(client, d, w, h, flags, format); 1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 15823165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceBlur: 15833165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 1584921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createDimLayer(client, d, w, h, flags); 1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 15863165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceScreenshot: 1587921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createScreenshotLayer(client, d, w, h, flags); 1588118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 159296f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1593285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 159496f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 15968b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 159796f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 15991c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 160096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1606921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 1607f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 160896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 16091c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 161292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1618a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1619a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1620a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 16218f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1622a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1626a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1627a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1628a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1629a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1630a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 163196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1632f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 163399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1634921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1635076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1640921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 1641f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 164296f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 164496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1645118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1646118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1647118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1648921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 1649118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1650118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1651118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1652118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1656921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 16579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 16589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 16599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 16609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 16618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 16620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 16630aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 16640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 16659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 16669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 166748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 16680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 166996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1670b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 167148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 167248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 167348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 167413233e067b8f71adc3a0ade5f442265e1f27084bMathias Agopian setTransactionFlags(eTransactionNeeded); 167548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 16769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 16779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 16789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 16799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1680921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1682759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1683ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1684ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1685ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1686ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1687ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1688ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1689ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1690ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1691ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1692ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1693e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1694ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1695f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1696e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1697ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1698ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1699ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1702b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1703b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1704b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 17058e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 17064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice 17078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().acquire(); 17084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->acquireScreen(); 170922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 171020128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian mVisibleRegionsDirty = true; 171120128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian repaintEverything(); 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1714b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 17158e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 17164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice 17174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->isScreenAcquired()) { 171822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 17194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->releaseScreen(); 17208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().release(); 1721b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1722b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1723b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1724b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 17258e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1726b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1727b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1728b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1729b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1730b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1731b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1732b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1733b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1734b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1735b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1736b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17398e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1740b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1741b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1742b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1743b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1744b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1745b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1746b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1747b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1748b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1749b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1750b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1751b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1752b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1753b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1754b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17571d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 176099b49840d309727678b77403d6cc9f920111623fMathias Agopian 176199b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 17689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 17699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 17709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 17719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 17729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 17739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 17749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 17759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 17769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 17778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 17789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 17799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 17809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 17819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 17829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 178525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 178625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 178725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 178825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 178925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 179025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 179135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 179225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 179325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 179425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 179525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 179835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 180025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 180125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 180225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 180325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 180425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 180535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 180625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 181248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 181548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 182048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 182125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 182225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 182325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 182425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 182525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 182625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 182725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 182825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 182925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 183025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 183125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 183225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 183782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 184148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1855ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 185625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 185725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 185825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 185925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 186025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 186125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 186225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 186325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 186425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 186525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 186625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 186725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 186825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 186925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 187025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 187125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 187225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 187325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 187425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 188182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 188282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 188382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1884bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 188582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 188682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 188782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 188882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 188982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 189082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 189182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 189282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1896bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 189982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1900ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 190182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 190282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 190382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 190482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 190582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 190682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 190782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 19081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 190982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 19105f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 19115f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 19125f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 19135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 19145f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 19155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian snprintf(buffer, SIZE, 19165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian "+ DisplayDevice[%u]\n" 19175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian " id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, " 19185f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian "flips=%u, secure=%d, numLayers=%u\n", 19195f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian dpy, 19205f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getDisplayId(), hw->getLayerStack(), 19215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getWidth(), hw->getHeight(), 19225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getOrientation(), hw->getTransform().getType(), 19235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getPageFlipCount(), 19245f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getSecureLayerVisible(), 19255f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian hw->getVisibleLayersSortedByZ().size()); 19265f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian result.append(buffer); 19275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 19285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 19295f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 193082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 193182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 19321b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 193382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 193482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 19351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1936888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 19374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 193882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 193982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 194082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 194182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 194282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 194382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1944d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 194582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 1946d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID)); 194782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 194873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 194982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 195082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 19519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 19524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 195382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 195482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 19554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getOrientation(), hw->canDraw()); 195682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 195782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 195882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 195982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1960c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 196182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 196282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 19638b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian " y-dpi : %f\n", 196482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 196582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1966c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 1967888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian 1e9 / hwc.getRefreshPeriod(), 19688b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian hwc.getDpiX(), 19698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian hwc.getDpiY()); 197082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 197182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 197282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 197382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 197482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 197582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 197682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 197782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 197882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 197982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 198082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 198182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 198282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 198382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 198482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 198582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 198682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 198782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 198882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 198982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 199082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 199182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 199282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 199382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 19944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ()); 199582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 199682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 199782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 199882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 199982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 200082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 20014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dump(result); 2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2009698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 20118e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 20128e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 2013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2017a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 201899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 201999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2020e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2021375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2022375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 20241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 20251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 20261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 20271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 20281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 20291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 20301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 20311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 203299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 203399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2034e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 20351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 20361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 20371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 20381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 20411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2044b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 204599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2046375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2047375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2048375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2049e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2050375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 205501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 205635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 206153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 206253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 206553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2066cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2067cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2068cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2069e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2070e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2071e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2072e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2073cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 20754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 20764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 20774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 20784d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 207953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 208053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 208153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 208253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 208353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 208453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2085a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2086a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2087a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2088a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2089a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2090a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 209201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2095b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 209612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 21004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 21014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 211087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 211199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 211253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 211353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 211459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 211559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2116118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 2117118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2118118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2119118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 2120118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 2121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2122118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 212622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 212722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 212859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 212959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 213059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 213159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 21324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(dpy)); 21334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 21344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 213559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 213659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 213759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 213859119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 213959119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 214059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 214159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 214259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 214359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 214459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2145a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2146a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 214959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2150015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 215159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 215259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 215559119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 215659119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 215759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 215859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 215959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 216259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2164c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2165c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2168a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2169a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 21704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 2174fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian layer->draw(hw); 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 217659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2178118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2194bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2195bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 219674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2197fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2198fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 219974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 220074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 220174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 22023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { 2203ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGE("invalid display %d", dpy); 220474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 22053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 22073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 22093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 22124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(dpy)); 22134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 22144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 221574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 22163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 22174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getSecureLayerVisible()) { 2218ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 22193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 22203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 22213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 22223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 2223ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h); 222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 22253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 222774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 2230fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian const bool filtering = sw != hw_w || sh != hw_h; 223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2232ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2233ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// sw, sh, minLayerZ, maxLayerZ); 2234c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 223974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 224074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2243fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 224474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2250c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 225474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 225774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2258ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 225974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 226074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 226174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 226374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2264f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 22659575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 22669575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 226774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 226874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2269b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 22703165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian if (!(flags & layer_state_t::eLayerHidden)) { 2271b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2272b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2273fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian if (filtering) layer->setFiltering(true); 2274fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian layer->draw(hw); 2275fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian if (filtering) layer->setFiltering(false); 2276b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2277bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 228874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 228974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2292fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2317e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 23184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 2319e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2320ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2321c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 232474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 232574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 23271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2329bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 23311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 23321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 233399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 23341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 23351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 23371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 23381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 23401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 23411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 23421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 23431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 23441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 23451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2348bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2349bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 23501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 23511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 23521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2354bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2355bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 23561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2357bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2358bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2359bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 23601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 23611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 23621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 23631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 23641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 23651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 23661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2368bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 23691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 23701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 23711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 23721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2374bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 23751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 23761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 23771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 23781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 23791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 23801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 23811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 23831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2384921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2386921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2387921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2389921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2390921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2391921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2392921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2394be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 2395921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2396921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2397be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2398be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t ls = l->currentState().layerStack; 2399be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian uint32_t rs = r->currentState().layerStack; 2400be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 2401be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 2402be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2403921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2404921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2405be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 2406be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 2407be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 2408be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 2409921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2410921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2411921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2412921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2413e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) { 2414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id) 2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : id(id), layerStack(0), orientation(0) { 2418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 24197303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2420b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 242196f0819f81293076e652792794a961543e6750d7Mathias Agopian 24229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 24239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 24249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 24259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 24269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2427d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 24289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 24299a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2430d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2431a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2432d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2433d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2434d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2435e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2436a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2437a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 24389a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 24399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 24409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 24419a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 24429a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 24439a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 24449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2446