SurfaceFlinger.cpp revision c666cae2d5995097ec49a87e375e2afdd92802b7
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 37d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h> 38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h> 40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 43d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 471c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 531b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.h" 54db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 55d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 59118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 62a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 63a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 65a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopian 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 87a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 88abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 92a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 973330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface(EGL_NO_SURFACE) 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 1083854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING 1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1145df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else 1155df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled" 1163854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif 1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugRegion, "showupdates enabled"); 119a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 138a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian Vector<DisplayState> displays; 1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian DisplayState d; 1498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian d.orientation = eOrientationDefault; 1508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian displays.add(d); 1518b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian setTransactionState(state, displays, 0); 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 154a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1577e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 16096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 16196f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16396f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 173b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 178a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1793330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 185921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 189a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 190a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 191a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 194921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 195921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 196921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian GLuint texture; 197921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 198921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageDestroyGLTexture(GLuint texture) 199921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : texture(texture) { 200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 201921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 202921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian glDeleteTextures(1, &texture); 203921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 204921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 205921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 206921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(texture)); 207921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 208921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat( 210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 211a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 212a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian PixelFormat format, 213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian for (int i=0 ; i<n ; i++) { 221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint nativeVisualId = 0; 222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); 223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (nativeVisualId>0 && format == nativeVisualId) { 224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian *outConfig = configs[i]; 225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 226a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 227a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 228a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 233a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint attribs[] = { 240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_RECORDABLE_ANDROID, EGL_TRUE, 242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE 243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (err) { 246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // maybe we failed because of EGL_RECORDABLE_ANDROID 247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); 248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian attribs[2] = EGL_NONE; 249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); 252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { 253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) { 275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext); 276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!result) { 277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Couldn't create a working GLES context. check logs. exiting..."); 278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 2908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint w, h; 292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_WIDTH, &w); 293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_HEIGHT, &h); 2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 2977303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 307a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 308a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 3139575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 3219575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 3229575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 3239575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 3249575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3279575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3299575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3309575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 3319575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 336ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 337ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize EGL 366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglInitialize(display, NULL, NULL); 368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Initialize the main display 370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create native window to main display 371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian sp<FramebufferSurface> anw = FramebufferSurface::create(); 372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ANativeWindow* const window = anw.get(); 373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!window) { 374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Display subsystem failed to initialize. check logs. exiting..."); 375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian int format; 380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian window->query(window, NATIVE_WINDOW_FORMAT, &format); 381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig = selectEGLConfig(display, format); 382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLContext = createGLContext(display, mEGLConfig); 383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize our main display hardware 385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig); 386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mDisplayHardwares[0] = hw; 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLSurface surface = hw->getEGLSurface(); 390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian initializeGL(display, surface); 391d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 392028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 393028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventThread = new EventThread(this); 394028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian mEventQueue.setEventThread(mEventThread); 395028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 3968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian // initialize the H/W composer 3978630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mHwc = new HWComposer(this, 3988630320433bd15aca239522e54e711ef6372ab07Mathias Agopian *static_cast<HWComposer::EventHandler *>(this), 3998630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hw->getRefreshPeriod()); 4008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian if (mHwc->initCheck() == NO_ERROR) { 4018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mHwc->setFrameBuffer(display, surface); 4028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian } 4038630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 405d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 406d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 407a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 408a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 4098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 413a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 414a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 415a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 416a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 417a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 418a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 420a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 422a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 423a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 424a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 425a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 426a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 427a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 429d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 430582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 431582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 432134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 433582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 434134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 435134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 436134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 437134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 438134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 439134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 440134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 441582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 442582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 443582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 444582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 445582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 446134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 447134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 448134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 449134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 450582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 451582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 458134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 463582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 464582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 468134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 471c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) { 472c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian if (uint32_t(dpy) >= 2) { 473c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian return BAD_INDEX; 474c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 475c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 476c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian return hw.getInfo(info); 477c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 478c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 479d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 480d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 481d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 4828aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 483bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 484bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { 4861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface result = EGL_NO_SURFACE; 4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface old_surface = EGL_NO_SURFACE; 4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian sp<SurfaceTextureClient> stc; 4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (display != NULL) { 4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian stc = new SurfaceTextureClient(display); 4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian result = eglCreateWindowSurface(hw.getEGLDisplay(), 494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig, (EGLNativeWindowType)stc.get(), NULL); 4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(result == EGL_NO_SURFACE, 4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian "eglCreateWindowSurface failed (ISurfaceTexture=%p)", 4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian display.get()); 4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian old_surface = mExternalDisplaySurface; 5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplayNativeWindow = stc; 5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface = result; 5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGD("mExternalDisplaySurface = %p", result); 5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (old_surface != EGL_NO_SURFACE) { 5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // Note: EGL allows to destroy an object while its current 5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // it will fail to become current next time though. 5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglDestroySurface(hw.getEGLDisplay(), old_surface); 5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const { 5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian return mExternalDisplaySurface; 5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 52699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 54599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 55099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 55499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5578630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) { 5588630320433bd15aca239522e54e711ef6372ab07Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 5598630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hw.onVSyncReceived(timestamp); 5608630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mEventThread->onVSyncReceived(dpy, timestamp); 5618630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 5628630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 5638630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) { 5648630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().eventControl(event, enabled); 5658630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 5668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 5681c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 56999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 5714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 5724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 5734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 5744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 5774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 5834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 5844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 5864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransaction(transactionFlags); 5874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 5884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 5894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 5934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 5944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handlePageFlip(); 5954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 5964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 5974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 5983a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 5994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 6004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRefresh(); 601a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 6023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (mVisibleRegionsDirty) { 6033b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region opaqueRegion; 6043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region dirtyRegion; 6053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 6063b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion); 6073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mDirtyRegion.orSelf(dirtyRegion); 6083b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian /* 6103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian * rebuild the visible layer list per screen 6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian */ 6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: iterate through all displays 6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); 6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const size_t count = currentLayers.size(); 6183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!currentLayers[i]->visibleRegion.isEmpty()) { 6203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: also check that this layer is associated to this display 6213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layersSortedByZ.add(currentLayers[i]); 6223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6243b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.setVisibleLayersSortedByZ(layersSortedByZ); 6253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // FIXME: mWormholeRegion needs to be calculated per screen 6283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here 6293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mWormholeRegion = Region(hw.getBounds()).subtract( 6303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.getTransform().transform(opaqueRegion) ); 6313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty = false; 6323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian invalidateHwcGeometry(); 6333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6343b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen, we should check all of them 6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (mDirtyRegion.isEmpty()) { 6384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return; 6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 640303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: iterate through all displays 6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const DisplayHardware& hw(getDisplayHardware(0)); 64369a655caef30663403802281210363f643ceb946Mathias Agopian 6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region into this screen's coordinate space 6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& planeTransform(hw.getTransform()); 6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion = planeTransform.transform(mDirtyRegion); 6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.andSelf(hw.bounds()); 650303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 651b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 6524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // build the h/w work list 6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleWorkList(hw); 6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6563094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_LIKELY(hw.canDraw())) { 6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // repaint the framebuffer (if needed) 6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRepaint(hw); 6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // inform the h/w that we're done compositing 6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian postFramebuffer(); 6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // pretend we did the post 6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // render to the external display if we have one 6694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface externalDisplaySurface = getExternalDisplaySurface(); 6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (externalDisplaySurface != EGL_NO_SURFACE) { 6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface cur = eglGetCurrentSurface(EGL_DRAW); 6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(), 6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian externalDisplaySurface, externalDisplaySurface, 6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian eglGetCurrentContext()); 6754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> external failed"); 6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (success) { 6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // redraw the screen entirely... 6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 6814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_2D); 6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClearColor(0,0,0,1); 6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glMatrixMode(GL_MODELVIEW); 6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glLoadIdentity(); 6863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); 6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = layers.size(); 6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; ++i) { 6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian layer->drawForSreenShot(hw); 6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface); 6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "external display eglSwapBuffers failed"); 6963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglMakeCurrent(eglGetCurrentDisplay(), 7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian cur, cur, eglGetCurrentContext()); 7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> internal failed"); 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 7054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 710841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 711b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 712b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 713b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 714b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 715b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 7161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 7178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 7183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 7193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian size_t numLayers = layers.size(); 720a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 721a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 722c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 723c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (hwc.initCheck() == NO_ERROR) { 724c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 725c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall const HWComposer::LayerListIterator end = hwc.end(); 726c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 727c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (cur->getCompositionType() == HWC_OVERLAY) { 7283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->setAcquireFence(*cur); 729c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } else { 730c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall cur->setAcquireFenceFd(-1); 731c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 732c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 733c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 734c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 735a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 7368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hwc.commit(); 737e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 738ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 739ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 740ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 741ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 7423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(&*cur); 743ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 744ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 745ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 7463b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(NULL); 747ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 748e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 749e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 750a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 751a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 752a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 757841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 758841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 7594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 761ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 762ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 763ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 764ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 765ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 766ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 767ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 768ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 769ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 772ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 7734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransactionLocked(transactionFlags); 774ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 775ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 776ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 777ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 778ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 7804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 7813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 7843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 7854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 797076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const int dpy = 0; // TODO: should be a parameter 8171b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 81898a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian hw.setOrientation(mCurrentState.orientation); 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8201b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware? 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8250aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 8260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8300aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 8310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 8320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 83348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 8363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 8373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 8390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 8400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could traverse the tree from front to back and compute the actual visible region 8424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could cache the transformed region 8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Layer::State front(layer->drawingState()); 8444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region visibleReg = front.transform.transform( 8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region(Rect(front.active.w, front.active.h))); 8464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf(visibleReg); 8470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 8480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 8574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 8584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 8594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 8604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 8614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 8624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 8674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransationPending = false; 8684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 8721bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 874841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 875841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian dirtyRegion.clear(); 881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 884076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 887970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 894ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 908ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 909ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 91099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 911a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 9124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 915ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 916ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 9174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region transparentRegionScreen; 9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 9194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 9204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 9214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 9224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = tr.transform(s.transparentRegion); 9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 9254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 9264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen.clear(); 9274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = s.transparentRegion; 9304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian visibleRegion.subtractSelf(transparentRegionScreen); 932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 9354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 938ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 939ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 940ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 944ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 948ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 949ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 9584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 961a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 963ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 970ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 972a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 973ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 9744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 9754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 976ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 977ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 984ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 9868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip() 996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9971c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 9984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 99999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 10001bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 10034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 10044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 10054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 10064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 10074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) ); 10084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10094da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 10103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 10110dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 10124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1015ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1016ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1017ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1018ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1019ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 102099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 102199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 102299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 102499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 102599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 102699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 102799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 102899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 103399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 103499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 103599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 10371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw) 1038a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 1039a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 10408630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 1041a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 10423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); 1043a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 1044a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 10453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 10463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 10473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 10483e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian currentLayers[i]->setGeometry(hw, *cur); 105053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 10513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 105273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 1053a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1054a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1055a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 1056b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 10571b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw) 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1059841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1060841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1061b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 10620656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 10651b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian debugFlashRegions(hw); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1068b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 1069b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 1070b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 1073a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 107429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 107529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 107629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 1077a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 107995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 108029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1081df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 108295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 108329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 10840656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 108629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 10880656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian setupHardwareComposer(hw); 10931b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, mDirtyRegion); 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10959c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 10969c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) 1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 11033e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 11043e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 11053e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 11069c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1108a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 11093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 111045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 1111a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1112e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 111345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 111445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 1115a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 111645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 111724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 111824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 111924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 1120a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 112145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 112245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 112345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 112445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 11253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1126f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11273e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 1128f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 1129f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 1130e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 1131f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 1132f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 11331b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) 1134f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 11358630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 11363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 11373e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 1138cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 1139cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 11403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 1141a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 114245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 1143b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 1144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1145b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1146b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1147b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1148b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1149b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1150b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1151b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1152b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 1153b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 1154b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 1155b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 1156b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1157a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 11584b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1159a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 1160a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 1161a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 11624b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 11633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 1164a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 11654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& tr = hw.getTransform(); 1166a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall for (size_t i=0 ; i<count ; ++i) { 1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 1169a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 1170a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end && cur->getCompositionType() == HWC_OVERLAY) { 11713e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1172a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 1173b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 1174b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 11751b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->clearWithOpenGL(hw, clip); 1176a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 11776ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall ++cur; 1178a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1179a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1180a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 11811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->draw(hw, clip); 11824b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1183a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end) { 1184a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall ++cur; 1185a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 11864b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 11874b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw) 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11920a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 119353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 11940656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 119553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 119653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 11970a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1198a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 11990a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 12000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 12011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, repaint); 12020a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 12030a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1204c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1205c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12080926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 12090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 12100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 12110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 12120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 12130a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 12140926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 121620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 121720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 121820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 121920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 122153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 122253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 122353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 122453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 12300656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 12330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1243b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1245b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1250f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1251f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1252f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1253f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1254f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1255f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1256f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1257f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1258f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1259f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1260f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1261f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1262f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 126596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 126696f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 12671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 126896f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 12694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 12704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 127196f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1272921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1273921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 127496f0819f81293076e652792794a961543e6750d7Mathias Agopian 12754f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 127696f0819f81293076e652792794a961543e6750d7Mathias Agopian} 127796f0819f81293076e652792794a961543e6750d7Mathias Agopian 127896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 127996f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 128096f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 128196f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 128296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 128396f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 128496f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1287076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12943d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 12989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 129976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 130076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 13019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 130276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 130376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 130476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 13058c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 13062f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 13070b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 13083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 13093d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 131096f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 131196f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 13129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 13139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1315dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1316dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1317dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1318dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1319dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1325bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 132999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13358b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 13368b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 13378b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 13388b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 13398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 1340698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 13428b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian int orientation = eOrientationUnchanged; 13438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian if (displays.size()) { 13448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian // TODO: handle all displays 13458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian orientation = displays[0].orientation; 13468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian } 13478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian 134828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1349b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1350b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1351b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 135228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1353b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 135432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1356b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1357b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1359698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1360698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1361698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1362698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 136328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1365386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 136628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1367386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 136828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1370386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1371386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1372386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1373386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 138032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1384cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 13890ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13900ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 13910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1395076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 13976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 13986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1399921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 14006e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 14016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 14038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1404921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1407921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createNormalLayer(client, d, w, h, flags, format); 1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 14101293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 14111293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 1413921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createDimLayer(client, d, w, h, flags); 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1415118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createScreenshotLayer(client, d, w, h, flags); 1417118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 142196f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1422285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 142396f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 14258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 142696f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1427a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 14281c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 142996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1435921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 1436f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 143796f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 14381c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1447a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1448a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1449a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 14508f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1451a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1455a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1456a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1457a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1458a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1459a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 146096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1461f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 146299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1463921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1469921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 1470f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 147196f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 147396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1474118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1475118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1476118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1477921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 1478118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1479118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1480118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1481118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1485921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 14869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 14879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 14889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 14899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 14908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 14910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 14920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 14930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 14949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 14959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 149648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 14970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 149896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1499b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 150048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 150148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 150248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 150348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 150448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 15059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 15069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 15089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1509921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1511759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1522e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1524f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1525e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1531698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 153296f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1533698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1536698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1537698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1538698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1539698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1540698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1541698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1542698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1543698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1544698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1547698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1569698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1574f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1575f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1576f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1577f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 15788785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian if (what & eLayerStackChanged) { 15798785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian if (layer->setLayerStack(s.layerStack)) 15808785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian flags |= eTraversalNeeded; 15818785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian } 1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1586b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1587b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1588b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 15898e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 15901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 15918630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().acquire(); 1592b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 159322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1594b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 159722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 15988acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 16028e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 16031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 160522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1606b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 16078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().release(); 1608b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1609b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1610b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1611b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 16128e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16268e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1631b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1632b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1633b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16441d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 164799b49840d309727678b77403d6cc9f920111623fMathias Agopian 164899b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 16559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 16569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 16579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 16589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 16599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 16609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 16619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 16648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 167225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 167325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 167425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 167525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 167625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 167725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 167835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 168535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 169025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 169125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 169235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 169325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 169948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 170248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 170748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 170825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 170925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 171025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 171125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 171225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 171325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 171425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 172848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1742ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 174325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 174425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 174525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 174625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 174725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 174825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 174925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 176282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 176382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 176482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 176582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 176682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 176782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 176882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1771bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1783bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1787ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 17951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 17991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 18031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 180882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1810d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 18121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian eglQueryString(hw.getEGLDisplay(), 181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 181573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 182182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 182482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1827c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1830b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1831b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1834c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1838b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 18578630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ()); 186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1879698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 188259119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 18848e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 18858e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1890a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 189199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 189299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1893e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1894375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1895375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 18971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 18981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 18991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 19001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 19011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 19021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 19031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 190599b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 190699b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1907e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1917b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 191899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1919375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1920375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1921375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1922e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1923375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 192801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 192935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 193453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 193553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 193853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1939cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1940cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1941cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1942cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1943cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 19464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 19474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 19484d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 194953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 195053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 195153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 195253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 195353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 195453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1955a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1956a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1957a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1958a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1959a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1960a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 196201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1965b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 196612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 19701b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 197953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 19801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display 19810dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 19820dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 198399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 198453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 198553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 19860dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 19870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 19890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 19900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 19910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 19920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 199859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 199959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2000118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 2001118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2002118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2003118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 2004118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 2005118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2006118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 200959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 201022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 201122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 201259119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 201359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 201459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 20161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 201759119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2029a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2034015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 204159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2048c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2049c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2052a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2053a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 20543b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 20581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 206059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2061118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 2062118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 207259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 207459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2075ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 2076ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 2077ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 2078ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 2079ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 2080ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 2081ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 2110a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 211159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 2114118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 2120a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2125b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2126b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2131ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 2132ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 2133ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2134ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 2135ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 2136ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 2137ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2171ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2172ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2173ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2174ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2189ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2190ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2191ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2192ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2196ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2197ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2200ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2201ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2202ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2203ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2204ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2210a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2211a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2212a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2213a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2214a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2215a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2224ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2225ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2226ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2262ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2263ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2264ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2265ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2275a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2276c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 22891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2307b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2308b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2362ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2363ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2364a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2365a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2377ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2378ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2379ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2380ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2387a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 239659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2397ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2398ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2399ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 240159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 242159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 242259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 242559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2426a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2427c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 24319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 24339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2434abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 24359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 243622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 243722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 24381b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 24437ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 24447ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 24458630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().disable(); 24467ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 24477ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 24487ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2449abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2450abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2451abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2452abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2453abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2454abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2455abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2458015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 245959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 246059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 246159119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 246259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 246359119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 246459119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2465abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 246759119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2468abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2469abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 247459119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 247559119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2476abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2481abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 24859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 24879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 24889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2489abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 249259119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 249359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2496abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 24979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 24981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 24999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 25009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 25019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2503abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2504abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2505abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2506a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2507a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2508a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 250999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2510a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2511015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 25129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 25159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 25179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2518abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2521abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2522abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 25289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2529abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2534abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 254074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 254174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 254274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2543bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2544bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 254574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2546fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2547fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 255074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 25513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { 255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25533b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25553b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 25573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 25601b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 256274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 25653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (hw.getSecureLayerVisible()) { 25663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 25673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 25683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 25693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 257274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 257374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 257474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 257574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 257674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25779d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 25781c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2579c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 258474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 258574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 258674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2588fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2595c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2603ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2609f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 26109575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 26119575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2614b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2615b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2616b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2617b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 26181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 2619b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2620bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 262174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 262274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 262374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 262474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 262574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 262674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 262774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2635fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2660e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2661e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2662e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 26639d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2664c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 266774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 26701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2672bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2673bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 26741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 26751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 267699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 26771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 26781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 26801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 268974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 269074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2691bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2692bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2697bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 26991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2700bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2701bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2702bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 27031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 27061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 27071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 27091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 271074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2711bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2717bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2727921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2728921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2729921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2730921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2731921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2732921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2733921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2734921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2735921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2737921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2738921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2739921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian // sort layers by Z order 2740921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2741921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2742921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian // then by sequence, so we get a stable ordering 2743921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence); 2744921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2745921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2746921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2747921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2748921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::State::State() 2749921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : orientation(ISurfaceComposer::eOrientationDefault), 2750921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian orientationFlags(0) { 2751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 27527303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2753b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 275496f0819f81293076e652792794a961543e6750d7Mathias Agopian 27559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 27569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 27589a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2760d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2763d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2764a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2765d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2766d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2767d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2768e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2769a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2770a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 27719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 27729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 27739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 27749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 27759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 27779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2779