SurfaceFlinger.cpp revision b60314a12f3336b27d73920805ab07cbc498d857
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 <stdlib.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 26a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 39d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h> 40d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 463330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h> 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 53d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 541f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 57118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 61a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 631db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h> 6490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h> 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), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground(0), 918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 983330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 106a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = atoi(value); 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1173854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING 1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1233854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif 1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugRegion, "showupdates enabled"); 126a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugBackground, "showbackground enabled"); 127a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian setTransactionState(state, eOrientationDefault, 0); 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian property_set("ctl.start", "bootanim"); 15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1607303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1637e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 16696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 16796f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16896f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16996f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 182e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 197a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1983330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 208a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.stop", "bootanim"); 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 217a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI( "SurfaceFlinger's main thread ready to run. " 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 233e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 236e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 298ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 299ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 301d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 302d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 3048aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 305f6de1c04ffc2c7a739578b7612944fddb7011ab7Mathias Agopian hw.startSleepManagement(); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 312d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 313a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 314a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 3158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 320d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 321582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 322582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 324582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 325134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 326134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 327134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 329134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 332582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 333582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 336582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 348134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 351582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 352582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 353582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 354582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 355582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 358134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 360134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 362d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 363d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 364d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 3658aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 366bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 367bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 36999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 37199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 37299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 37399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 39699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) 40799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 4081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 410303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian case MessageQueue::REFRESH: { 411303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// case MessageQueue::INVALIDATE: { 41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we're in a global transaction, don't do anything. 41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(transactionFlags)) { 41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleTransaction(transactionFlags); 41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // post surfaces (if needed) 42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handlePageFlip(); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 422303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// signalRefresh(); 423303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// 424303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// } break; 425303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// 426303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// case MessageQueue::REFRESH: { 4273a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 428c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian handleRefresh(); 429a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 430303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 431303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 432303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// if (mDirtyRegion.isEmpty()) { 433303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// return; 434303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// } 435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 436b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 437b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // build the h/w work list 438b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleWorkList(); 439b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian } 440303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 441b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_LIKELY(hw.canDraw())) { 442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // repaint the framebuffer (if needed) 443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleRepaint(); 444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // inform the h/w that we're done compositing 445b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian hw.compositionComplete(); 446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian postFramebuffer(); 447c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian } else { 448b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // pretend we did the post 449c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian hw.compositionComplete(); 45099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 451b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 45299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } break; 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 458841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 459b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 460b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 461b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 462b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 463b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 464a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 465a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 466a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 467a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 468e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 469e8696a40e09b24b634214684d18526187b316a2fJamie Gennis size_t numLayers = mVisibleLayersSortedByZ.size(); 470e8696a40e09b24b634214684d18526187b316a2fJamie Gennis for (size_t i = 0; i < numLayers; i++) { 471e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mVisibleLayersSortedByZ[i]->onLayerDisplayed(); 472e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 473e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 474a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 475a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 476a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 481841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 482841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 483ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 484ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 485ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 486ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 487ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 488ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 489ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 490ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 491ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 492ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 493ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 494ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 495ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 496ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 53721230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5590aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 56048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5685d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 5781bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 580841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 581841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 599970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 62299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 623a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 624970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 660a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 671a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 6858b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 690970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 696970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 697970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 698970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 699970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7072f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall if (!mLayersPendingRemoval.isEmpty()) { 7082f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall // Notify removed layers now that they can't be drawn from 7092f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 7102f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval[i]->onRemoved(); 7112f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7122f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.clear(); 7132f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7142f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 71628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending = false; 717cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const DisplayHardware& hw = graphicPlane(0).displayHardware(); 72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const Region screenRegion(hw.bounds()); 72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 7261bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 72799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const bool visibleRegions = lockPageFlip(currentLayers); 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (visibleRegions || mVisibleRegionsDirty) { 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7324da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7334da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7344da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7354da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7361bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 7374da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7384da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7394da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7404da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7414da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7424da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 746ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 7500dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 7510dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 755ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 756ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 757ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 758ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 759ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 764076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 766b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 77699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 777076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 779b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 78499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 78599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 78699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 78799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 78899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 78999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 79099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 79199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 79299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 79399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 79499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 79599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 79699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 79799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 79999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 801a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 802a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 803a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 804a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 805a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 806a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 807a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 808a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 80945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 81045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 81145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 81253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 81373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 81473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 81573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 819b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 822841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 823841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 824b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8250656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 82799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 831b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 832b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 834b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 8378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 8388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 839df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 84029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 84129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 84229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 84329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 844b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 84529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 8460656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 84729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 84829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 84929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 85029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 85129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 85495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 856df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 85795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 8590656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 8630656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian setupHardwareComposer(mDirtyRegion); 868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 8719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 877f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 878f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 879f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 880f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!cur) { 8819c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 883a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 8844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 88545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 886a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 887e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 88845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 88945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 89224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 89324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 89424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 89845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 89945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 900f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 901f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 902f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian layer->setPerFrameData(&cur[i]); 903f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 905f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 906e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 908f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (err == NO_ERROR) { 9099c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // what's happening here is tricky. 9109c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we want to clear all the layers with the CLEAR_FB flags 9119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that are opaque. 9129c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // however, since some GPU are efficient at preserving 9139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the backbuffer, we want to take advantage of that so we do the 9149c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // clear only in the dirty region (other areas will be preserved 9159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // on those GPUs). 9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // NOTE: on non backbuffer preserving GPU, the dirty region 9179c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // has already been expanded as needed, so the code is correct 9189c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // there too. 9199c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9209c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // However, the content of the framebuffer cannot be trusted when 9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we switch to/from FB/OVERLAY, in which case we need to 9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // expand the dirty region to those areas too. 9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Note also that there is a special case when switching from 9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // "no layers in FB" to "some layers in FB", where we need to redraw 9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the entire FB, since some areas might contain uninitialized 9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // data. 9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Also we want to make sure to not clear areas that belong to 9303a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // layers above that won't redraw (we would just be erasing them), 9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that is, we can't erase anything outside the dirty region. 932a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian Region transparent; 934f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { 9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.set(hw.getBounds()); 9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut = transparent; 9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } else { 9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian for (size_t i=0 ; i<count ; i++) { 9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const sp<LayerBase>& layer(layers[i]); 9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { 9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.orSelf(layer->visibleRegionScreen); 9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); 9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (isOverlay != layer->isOverlay()) { 9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we transitioned to/from overlay, so add this layer 9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // to the dirty region so the framebuffer can be either 9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // cleared or redrawn. 9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut.orSelf(layer->visibleRegionScreen); 9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian layer->setOverlay(isOverlay); 952f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // don't erase stuff outside the dirty region 9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.andSelf(dirtyInOut); 955f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 957f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian /* 958f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian * clear the area of the FB that need to be transparent 959f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian */ 960f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!transparent.isEmpty()) { 961f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClearColor(0,0,0,0); 962f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator it = transparent.begin(); 963f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator const end = transparent.end(); 964f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const int32_t height = hw.getHeight(); 965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian while (it != end) { 966f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Rect& r(*it++); 967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const GLint sy = height - (r.top + r.height()); 968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 970f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian } 971a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 972a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 977cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 978cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 979cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 980cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 98199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) { 982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // should never happen unless the window manager has a bug 983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // draw something... 984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian drawWormhole(); 985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 98645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 98745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 98845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 98945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 9904b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 992f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian size_t count = layers.size(); 9944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 9954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 9964b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian // FIXME: workaround for b/6020860 9974b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian if (hw.getFlags() & DisplayHardware::BUFFER_PRESERVED) { 9984b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian for (size_t i=0 ; i<count ; i++) { 9994b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian if (cur && (cur[i].compositionType == HWC_FRAMEBUFFER)) { 10004b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian glEnable(GL_SCISSOR_TEST); 10014b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian glScissor(0,0,0,0); 10024b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 10034b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian break; 10044b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10054b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10064b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10074b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian // FIXME: bug6020860 for b/6020860 10084b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 10094b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { 1012f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian continue; 101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 101445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 101545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 101645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 101745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 101845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 101945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 10250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 102653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10270656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 102853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 102953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 10330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 10360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1038c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1039c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 105220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 105320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 105420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 105653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 105753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 105853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 105953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10650656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10680a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!mDebugBackground)) { 10840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 108520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 108620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 108720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 108820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1097c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1101c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1102c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1108c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1109c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 1110c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 111220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 111320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 111420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 111520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1121a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 1122ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glLoadIdentity(); 1123ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glMatrixMode(GL_MODELVIEW); 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1137f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11381b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 114196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 114296f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11431b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 114496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11454f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11464f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11474f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 114896f0819f81293076e652792794a961543e6750d7Mathias Agopian 114996f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 115096f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 115196f0819f81293076e652792794a961543e6750d7Mathias Agopian 11524f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 115396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 115496f0819f81293076e652792794a961543e6750d7Mathias Agopian 115596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 115696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 115796f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 115896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 115996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 116096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 116196f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1164076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1166b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1167b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11680d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1169b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1172076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 118076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 118176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 118376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 118476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 118576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 11880b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 119196f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 119296f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 119696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 119896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 119996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 120096f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1203dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1204dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1205dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1206dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1207dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1213bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 121799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1223b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 122428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1225698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1226cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 122728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1228b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1229b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1230b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 123128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1232b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 123332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1234b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1235b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1236b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1237b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1239698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1240698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 124228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1243698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 124528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1246386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 124728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1248698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1249386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1253386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1254386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1255386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1256386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1257386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1258386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 125932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1261386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1262386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1263cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 12680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 12690ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 12700ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1274076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1275a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 12766e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1278e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12796e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12816e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12828b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1283ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1287a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1288a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12911293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12921293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 129496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1296118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1297118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1298118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1301076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 130296f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1303285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 130496f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 13078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 130896f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1309a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1312a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 13141c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 131696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1323f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 132496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 13251c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1334a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1335a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 13378f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1338a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1342a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1343a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1344a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1345a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1346a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 134796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1348f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 134999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1350e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1351076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1356b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1357f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 135896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 136096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1361118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1362118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1363118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1365118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1366118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1367118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1368118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 137296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13739a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13780aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 138348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 138596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1386b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 138748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 138848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 138948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 139048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 139148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1398759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1399ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1406ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1407ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1408ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1409e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1410ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1411f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1412e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1413ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1414ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1415ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 141996f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1434698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1458698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1465b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1469b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 1470b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1471b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1472b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian mDirtyRegion.set(hw.bounds()); 1474b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will priocess updates again 1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1477b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian mDirtyRegion.set(hw.bounds()); 1481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1483b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::screenAcquired() { 1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1493b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1494b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1495b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1496b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1497b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1500b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::screenReleased() { 1501b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1502b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1503b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1504b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1505b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1506b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1507b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1508b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1509b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1510b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1511b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1512b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1513b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1514b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1515b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15181d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 152199b49840d309727678b77403d6cc9f920111623fMathias Agopian 152299b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 154482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 154582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 154925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 155235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 155425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 155525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 155625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 155882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 155935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 156082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 156635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 157082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 157348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 157648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 158082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 158148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 158225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 158325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 158425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 158525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 158625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 158725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 158825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 158925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 159025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 159125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 159225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 159325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 159482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 159682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 159982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 160248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 160482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 160682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 161182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1616ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 161725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 161825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 161925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 162025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 162125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 162225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 162325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 162425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 162525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 162625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 162725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 162825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 162925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 163025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 163125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 163225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 163325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 163425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 163525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1645bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 165482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1657bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1661ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 166682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 16691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 16731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1683d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 168582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian eglQueryString(graphicPlane(0).getEGLDisplay(), 168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 168873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1701c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1704b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1705b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1708c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1711b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1712b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1753698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 175659119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1762a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 176399b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 176499b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1765e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1766375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1767375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 17701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 17721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 17731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 17741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 177799b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 177899b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1779e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 17801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1789b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 179099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1791375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1792375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1793375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1794e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1795375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 180001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 180135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 180753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 181453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1815cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1816cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1817cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1818cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1819cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 18214d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 18224d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 18234d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 18244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 182553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 182653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 182753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 182853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 182953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 183053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1831a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1832a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1833a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1834a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1835a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1836a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 183801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 184212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 185553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 185653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18570dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 18580dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 185999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 186053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 186153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 18620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 18630dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 18650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18660dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 18670dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 18680dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18690dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 18700dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 18710dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 18720dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18730dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 187459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 187559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1876118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1877118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1878118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1879118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1880118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1881118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1882118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 188559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 189559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 189659119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 189959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 190059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 190159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 190259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 190559119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1906015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 190759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 190859119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 191259119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 191359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 191459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 191559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 191859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1920c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1921c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 192262f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian glDisable(GL_SCISSOR_TEST); 19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 192562f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian glEnable(GL_SCISSOR_TEST); 1926a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1927a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 193459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1935118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1936118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 194159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 194759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 194959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1956a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 195759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1960118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 196459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1966a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1971b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1972b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1977ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1978ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1979ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1980ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1981ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1982ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1983ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1984ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1985ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1990ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1991ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1992ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2017ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2018ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2019ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2020ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2035ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2036ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2037ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2038ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2043ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2044ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2045ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2046ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2047ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2048ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2054a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2055a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2056a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2057a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2058a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 207259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 208959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 209059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2114c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2145b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2146b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 216959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2200a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2201a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2219a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 222859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 223059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 225059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 225159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2256a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2257c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 225859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2264abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22717ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 22727ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 22737ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 22747ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 22757ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 22767ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2277abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2278abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2279abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2280abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2281abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2282abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2283abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 2284abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2285abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 2286abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2287abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2288015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 229159119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 229459119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2295abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 229759119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2298abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2299abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 230059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 230159119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 230259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 230359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 230459119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 230559119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2306abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 230759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 230859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 230959119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 231059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2311abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 231259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 231459119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2319abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 232059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 232159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 232259119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 232359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2326abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2333abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2334abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2335abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2336a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2337a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2338a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 233999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2340a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2341015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2348abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2351abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2352abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2359abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2364abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2373bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2374bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2376fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2377fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 238199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23999d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 24001c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2401c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2410fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2417c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 2422f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian glScissor(0, 0, sw, sh); 2423ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2427ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2433f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 24349575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 24359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2438b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2439b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2440b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2441b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2442b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2443b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2444bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 2448ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 246174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2463fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 247374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 247474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 247774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 248074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 248174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 248274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 248374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2489e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2490e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2491e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 24929d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2493c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 249574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 249674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2501bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2502bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 250599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 251874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 251974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2520bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2521bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 25241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 252574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2526bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2527bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2529bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2530bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2531bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 25351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 25361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 25391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 25411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 254474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2545bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2552bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2562b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2564b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2565b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2566b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2567b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2568b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 25697303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 257196f0819f81293076e652792794a961543e6750d7Mathias Agopian 2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2573b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2574b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257796f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 257896f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 257996f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 258096f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 258196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 258296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 258396f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 258496f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 258896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2589b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 25924f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25944f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 25954f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = mNameGenerator++; 259696f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 259796f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 260196f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 26024f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 260396f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 260496f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 260596f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 260696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 260796f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 260896f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 260996f0819f81293076e652792794a961543e6750d7Mathias Agopian } 261096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 261196f0819f81293076e652792794a961543e6750d7Mathias Agopian} 26124f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const 26134f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{ 26144f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 2615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 26164f113740180b6512b43723c4728f262882dc9b45Mathias Agopian wp<LayerBaseClient> layer(mLayers.valueFor(i)); 261796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 261896f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 2619e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2624a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2625a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact( 2626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{ 2628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // these must be checked 2629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2630a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int pid = ipc->getCallingPid(); 2631a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int uid = ipc->getCallingUid(); 2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int self_pid = getpid(); 263399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // we're called from a different process, do the real check 263599b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2636a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2637e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2638a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2639a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return PERMISSION_DENIED; 2640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2645a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 264696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 26470ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 2648b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2649b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2652b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2653a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * createSurface must be called from the GL thread so that it can 2654a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * have access to the GL context. 2655b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2656b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2657a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class MessageCreateSurface : public MessageBase { 2658a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> result; 2659a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian SurfaceFlinger* flinger; 2660a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params; 2661a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian Client* client; 2662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name; 2663a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display; 2664a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w, h; 2665a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormat format; 2666a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags; 2667a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2668a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian MessageCreateSurface(SurfaceFlinger* flinger, 2669a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params, 2670a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name, Client* client, 2671a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2672a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags) 2673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : flinger(flinger), params(params), client(client), name(name), 2674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display(display), w(w), h(h), format(format), flags(flags) 2675a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2676579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2677a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> getResult() const { return result; } 2678a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual bool handler() { 2679a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian result = flinger->createSurface(params, name, client, 2680a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display, w, h, format, flags); 2681a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 2682b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2683a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 2684b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2685a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2686a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params, name, this, display, w, h, format, flags); 2687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFlinger->postMessageSync(msg); 2688a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2689b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2690a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 2691a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mFlinger->removeSurface(this, sid); 2692b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2693b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2694b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 26979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 26999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2701d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 27029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 27039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2704d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2705a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2706d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2707d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2708d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2709e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2710a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2711a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 27129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 27139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 27149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 27159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 27169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 27189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 27332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 27372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 27382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 27392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 27412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 27432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 27452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 27462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 27472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 27482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 27492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 27502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 27512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 27522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 27532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 27542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 27552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 27562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 27572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 27612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 27622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 27632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 27642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 27652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 27662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 27672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 27682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 27692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 27702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2777eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2778eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2781eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2782eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2784eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2787eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2790eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2795eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 28032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 28042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 28052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 28062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 28072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 28082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 28092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 28102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2811eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2812eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2813eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2814eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2815eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2817eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 28180d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 28192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 282759119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 282859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 282959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 283059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2835076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2836076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2837076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2838076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2842