SurfaceFlinger.cpp revision 35aadd6be249da4bd4851692e6aff757c91b32a7
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 "DisplayEventConnection.h" 54d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 58118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 62a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 641db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h> 6590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h> 66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8099b49840d309727678b77403d6cc9f920111623fMathias Agopian 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 88a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 89abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground(0), 928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 94a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 993330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mConsoleSignals(0), 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 108a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = atoi(value); 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 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 // check for transactions 41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(mConsoleSignals)) { 41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleConsoleEvents(); 41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we're in a global transaction, don't do anything. 41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(transactionFlags)) { 42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleTransaction(transactionFlags); 42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // post surfaces (if needed) 42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handlePageFlip(); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 427303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// signalRefresh(); 428303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// 429303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// } break; 430303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// 431303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// case MessageQueue::REFRESH: { 4323a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 433c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian handleRefresh(); 434a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 436303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 437303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// if (mDirtyRegion.isEmpty()) { 438303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// return; 439303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian// } 440303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 441b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // build the h/w work list 443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleWorkList(); 444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian } 445303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_LIKELY(hw.canDraw())) { 447b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // repaint the framebuffer (if needed) 448b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleRepaint(); 449b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // inform the h/w that we're done compositing 450b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian hw.compositionComplete(); 451b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian postFramebuffer(); 452c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian } else { 453b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // pretend we did the post 454c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian hw.compositionComplete(); 45599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 456b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 45799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } break; 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 463841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 464b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 465b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 466b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 467b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 468b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 469a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 470a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 471a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 472a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 473e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 474e8696a40e09b24b634214684d18526187b316a2fJamie Gennis size_t numLayers = mVisibleLayersSortedByZ.size(); 475e8696a40e09b24b634214684d18526187b316a2fJamie Gennis for (size_t i = 0; i < numLayers; i++) { 476e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mVisibleLayersSortedByZ[i]->onLayerDisplayed(); 477e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 478e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 479a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 480a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 481a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents() 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something to do with the console 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int what = android_atomic_and(0, &mConsoleSignals); 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleAcquired) { 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.acquireScreen(); 4929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // this is a temporary work-around, eventually this should be called 4939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager 494abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleReleased) { 49859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (hw.isScreenAcquired()) { 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 508841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 509841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5283d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5313d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5323d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 56421230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5850aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5860aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 58748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5890aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5955d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 6051bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 607841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 608841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 626970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 64999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 650a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 651970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 687a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 698a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 700ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 7128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 717970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 723970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 724970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 725970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 726970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7342f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall if (!mLayersPendingRemoval.isEmpty()) { 7352f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall // Notify removed layers now that they can't be drawn from 7362f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 7372f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval[i]->onRemoved(); 7382f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7392f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.clear(); 7402f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7412f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 74328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending = false; 744cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7491c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 75099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const DisplayHardware& hw = graphicPlane(0).displayHardware(); 75199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const Region screenRegion(hw.bounds()); 75299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 7531bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 75499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const bool visibleRegions = lockPageFlip(currentLayers); 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (visibleRegions || mVisibleRegionsDirty) { 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7614da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7624da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7631bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 7644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 773ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 7770dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 7780dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 782ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 783ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 784ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 785ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 786ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 791076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 80399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 804076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 806b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 81599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 81699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 81799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 81899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 81999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 82099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 82199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 82299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 82399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 82499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 82599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 82699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 82799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 828a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 829a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 834a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 835a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 83645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 83745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 83845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 83953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 84073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 84173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 84273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 843a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 844a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 845a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 849841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 850841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 851b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8520656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 85499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 858b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 859b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 860b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 861b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 8648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 8658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 866df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 86829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 86929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 871b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 87229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 8730656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 87429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 87529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 87629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 87729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 87829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 87929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 88195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 88229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 883df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 88495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 88529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 8860656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 88829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 8900656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian setupHardwareComposer(mDirtyRegion); 895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8979c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 8989c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9029c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) 903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 904f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 905f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 906f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!cur) { 9089c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 910a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 913a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 914e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 91545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 917a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 91924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 92024925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 92124925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 922a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 92345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 92445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 92545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 92645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 927f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 928f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 929f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian layer->setPerFrameData(&cur[i]); 930f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 932f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 933e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 934f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 935f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (err == NO_ERROR) { 9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // what's happening here is tricky. 9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we want to clear all the layers with the CLEAR_FB flags 9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that are opaque. 9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // however, since some GPU are efficient at preserving 9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the backbuffer, we want to take advantage of that so we do the 9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // clear only in the dirty region (other areas will be preserved 9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // on those GPUs). 9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // NOTE: on non backbuffer preserving GPU, the dirty region 9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // has already been expanded as needed, so the code is correct 9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // there too. 9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // However, the content of the framebuffer cannot be trusted when 9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we switch to/from FB/OVERLAY, in which case we need to 9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // expand the dirty region to those areas too. 9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Note also that there is a special case when switching from 9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // "no layers in FB" to "some layers in FB", where we need to redraw 9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the entire FB, since some areas might contain uninitialized 9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // data. 9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Also we want to make sure to not clear areas that belong to 9573a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // layers above that won't redraw (we would just be erasing them), 9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that is, we can't erase anything outside the dirty region. 959a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian Region transparent; 961f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { 9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.set(hw.getBounds()); 9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut = transparent; 9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } else { 9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian for (size_t i=0 ; i<count ; i++) { 9679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const sp<LayerBase>& layer(layers[i]); 9689c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { 9699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.orSelf(layer->visibleRegionScreen); 9709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); 9729c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (isOverlay != layer->isOverlay()) { 9739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we transitioned to/from overlay, so add this layer 9749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // to the dirty region so the framebuffer can be either 9759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // cleared or redrawn. 9769c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut.orSelf(layer->visibleRegionScreen); 9779c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9789c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian layer->setOverlay(isOverlay); 979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9809c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // don't erase stuff outside the dirty region 9819c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.andSelf(dirtyInOut); 982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian /* 985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian * clear the area of the FB that need to be transparent 986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian */ 987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!transparent.isEmpty()) { 988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClearColor(0,0,0,0); 989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator it = transparent.begin(); 990f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator const end = transparent.end(); 991f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const int32_t height = hw.getHeight(); 992f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian while (it != end) { 993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Rect& r(*it++); 994f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const GLint sy = height - (r.top + r.height()); 995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 997f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian } 998a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 999a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1000f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 1001f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 1002f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 1003f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 1004cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1005cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 1006cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 1007cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 100899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) { 1009f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // should never happen unless the window manager has a bug 1010f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // draw something... 1011f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian drawWormhole(); 1012f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 1014fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian // FIXME: workaroud for b/6020860 1015fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian glEnable(GL_SCISSOR_TEST); 1016fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian glScissor(0,0,0,0); 1017fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1018fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian // end-workaround 1019fbc7922ec87298601ba6a3be1bd9f83ffaf9a233Mathias Agopian 102045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 102145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 102245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 1023cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 1024f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1025f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian size_t count = layers.size(); 102645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { 1028f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian continue; 102945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 103045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 103145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 103245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 103345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 103445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 103545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 104253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10430656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 104453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 104553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 10480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 10490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 10520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1054c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 106820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 106920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 107020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 107253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 107353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 107453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 107553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!mDebugBackground)) { 11000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 110120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 110220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 110320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 110420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1113c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1117c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1118c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1124c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1125c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 1126c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 112820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 112920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 113020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 113120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1137a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 1138ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glLoadIdentity(); 1139ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glMatrixMode(GL_MODELVIEW); 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1151076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1153f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 115796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 115896f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 116096f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11624f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 116496f0819f81293076e652792794a961543e6750d7Mathias Agopian 116596f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 116696f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 116796f0819f81293076e652792794a961543e6750d7Mathias Agopian 11684f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 116996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 117096f0819f81293076e652792794a961543e6750d7Mathias Agopian 117196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 117296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 117396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 117496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 117596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 117696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 117796f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1180076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1182b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11840d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1185b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 119676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 119776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 119976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 120076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 120176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 12028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 12032f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 12040b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 12053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 12063d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 120796f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 120896f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 12099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 12109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 12119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 121296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 121496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 121596f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 121696f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1219dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1220dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1221dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1222dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1223dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1229bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 123399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1239b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 124028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1242cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 124328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1244b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1245b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1246b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 124728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1248b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 124932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1252b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1253b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1254698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1256698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1257698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 125828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1259698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 126128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1262386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 126328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1264698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1265386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1266386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1267386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1268386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1269386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1270386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1271386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1272386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1273386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1274386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 127532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1276386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1277386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1278386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1279cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12830ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 12840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 12850ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 12860ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1291a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 12926e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12936e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1294e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12956e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1299ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1303a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1304a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 13071293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 13081293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 131096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1312118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1313118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1314118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1317076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 131896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1319285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 132096f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 13238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 132496f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1325a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1328a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 13301c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1331b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 133296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1339f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 134096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 13411c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1350a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1351a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1352a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 13538f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1354a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1358a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1359a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1360a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1361a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1362a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 136396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1364f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 136599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1366e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1367076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1373f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 137496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 137696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1377118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1378118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1379118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1380118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1381118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1382118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1383118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1384118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 138896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 139948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 14000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 140196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 140248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 140348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 140448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 140548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 140648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 14079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 14089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 14099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 14109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1411ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1413759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1414ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1415ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1416ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1417ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1418ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1419ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1420ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1421ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1422ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1423ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1424e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1425ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1426f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1427e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1428ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1429ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1430ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 143496f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1451698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1452698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1454698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1457698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1461698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1464698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1465698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1466698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1469698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1470698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1471698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1473698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1474698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1475698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1477698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 148499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 149199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14961d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 149999b49840d309727678b77403d6cc9f920111623fMathias Agopian 150099b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 152382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 152425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 152525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 152625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 152725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 152825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 152925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 153035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 153125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 153225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 153325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 153425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 153682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 153735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 153882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 153925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 154435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 154882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 154982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 155082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 155148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 155282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 155382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 155448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 155682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 155882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 155948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 156625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 156825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 156925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 157025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 157125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 158482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1594ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 159525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 159625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 159725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 159825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 159925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 160025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 160125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 160225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 160325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 160425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 160525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 160625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 160725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 160825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 160925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 161025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 161125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 161225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 161325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 162282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1623bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 162482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 162782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 162882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 163182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 163482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1635bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1639ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 16471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 16511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1661d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian eglQueryString(graphicPlane(0).getEGLDisplay(), 166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 166673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1679c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " y-dpi : %f\n", 168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1685c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 168882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiY()); 168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1729698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 173259119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1738a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 173999b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 174099b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1741e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1742375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1743375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 17461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 17481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 17491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 17501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 175399b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 175499b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1755e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 17561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1765b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 176699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1767375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1768375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1769375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1770e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1771375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 177601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 177735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 178253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 178353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 179053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1791cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1792cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1795cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 17984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 17994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 18004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 180153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 180353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 180453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1807a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1808a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1809a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1810a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1811a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1812a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 181401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 181812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 183153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 183253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18330dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 18340dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 183599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 183653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 183753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 18380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 18390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18400dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 18410dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18420dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 18430dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 18440dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18450dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 18460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 18470dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 18480dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18490dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 185059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 185159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1852118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1853118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1854118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1855118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1856118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1857118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1858118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 186159119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 186259119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 186459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 186759119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 186859119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 187359119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 187459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 187559119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 187659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 187859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 188159119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1882015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 188359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1896c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1897c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 189862f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian glDisable(GL_SCISSOR_TEST); 18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 190162f7114719d2009dca7dd120f0fe29a24bd77a40Mathias Agopian glEnable(GL_SCISSOR_TEST); 1902a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1903a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 191059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1911118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1912118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1932a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 193359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1936118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 194059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1942a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1947b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1948b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1953ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1954ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1955ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1956ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1957ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1958ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1959ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1960ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1961ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1962ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1963ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1964ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1965ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1966ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1967ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1968ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2011ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2012ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2013ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2014ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2019ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2020ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2021ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2022ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2023ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2024ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2030a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2031a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2032a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2033a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2034a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2035a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 206559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2089a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2090c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2121b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2122b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 214559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2176a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2177a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2195a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 220459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 220659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 222659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 222759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2232a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2233c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2240abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22477ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 22487ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 22497ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 22507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 22517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 22527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2254abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2255abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2256abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2257abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2258abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2259abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 2260abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2261abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 2262abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2263abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2264015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 226559119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 226659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 226759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 226859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 226959119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2271abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 227359119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2274abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2275abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 227859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 228059119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 228159119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2282abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 228359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 228459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 228559119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 228659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2287abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2295abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 229759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 229859119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2309abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2310abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2311abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2312a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2313a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2314a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 231599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2316a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2317015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2324abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2328abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2335abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2349bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2350bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 235599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23739d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 23741c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2375c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2390c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 2395f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian glScissor(0, 0, sw, sh); 2396ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2400ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2406f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 24079575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 24089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2411b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2412b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2413b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2414b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2415b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2416b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2417bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 2421ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 245874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2461e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2462e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2463e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 24649d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2465c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2473bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2474bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 247799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 24811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 24851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 24861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 24871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 24891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2492bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2493bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2498bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2499bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2501bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2502bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2503bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 251674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2517bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2524bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2534b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2536b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2538b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2539b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2540b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 25417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2542b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 254396f0819f81293076e652792794a961543e6750d7Mathias Agopian 2544b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2545b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2546b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 254996f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 255096f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 255196f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 255296f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 255396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 255496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 255596f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 255696f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 256096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2561b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 25644f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25664f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 25674f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = mNameGenerator++; 256896f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 256996f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 257396f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 25744f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 257596f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 257696f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 257796f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 257896f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 257996f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 258096f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 258196f0819f81293076e652792794a961543e6750d7Mathias Agopian } 258296f0819f81293076e652792794a961543e6750d7Mathias Agopian } 258396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 25844f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const 25854f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{ 25864f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 2587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 25884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian wp<LayerBaseClient> layer(mLayers.valueFor(i)); 258996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 259096f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 2591e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact( 2598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2599a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{ 2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // these must be checked 2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2602a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int pid = ipc->getCallingPid(); 2603a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int uid = ipc->getCallingUid(); 2604a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int self_pid = getpid(); 260599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2606a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // we're called from a different process, do the real check 260799b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2609e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2611a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return PERMISSION_DENIED; 2612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 261896f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 26190ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 2620b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2624b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2625a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * createSurface must be called from the GL thread so that it can 2626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * have access to the GL context. 2627b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class MessageCreateSurface : public MessageBase { 2630a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> result; 2631a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian SurfaceFlinger* flinger; 2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params; 2633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian Client* client; 2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name; 2635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display; 2636a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w, h; 2637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormat format; 2638a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags; 2639a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian MessageCreateSurface(SurfaceFlinger* flinger, 2641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params, 2642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name, Client* client, 2643a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags) 2645a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : flinger(flinger), params(params), client(client), name(name), 2646a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display(display), w(w), h(h), format(format), flags(flags) 2647a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2648579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2649a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> getResult() const { return result; } 2650a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual bool handler() { 2651a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian result = flinger->createSurface(params, name, client, 2652a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display, w, h, format, flags); 2653a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 2654b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2655a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 2656b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2657a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2658a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params, name, this, display, w, h, format, flags); 2659a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFlinger->postMessageSync(msg); 2660a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2661b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 2663a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mFlinger->removeSurface(this, sid); 2664b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2665b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2666b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 26699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 26719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2673d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 26749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 26759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2676d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2677a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2678d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2679d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2680d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2681e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2682a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2683a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 26849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 26859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 26869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 26879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 26889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 26909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 27052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 27092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 27102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 27112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 27142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 27152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 27172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 27182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 27192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 27202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 27212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 27222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 27232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 27242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 27252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 27262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 27272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 27282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 27292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 27332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 27342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 27352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 27362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 27372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 27382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 27392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 27402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 27412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 27432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2749eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2750eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2753eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2754eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2756eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2759eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2762eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2767eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 27752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 27772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 27782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 27792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 27802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 27812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2783eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2784eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2785eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2786eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2787eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2789eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 27900d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 27912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 279959119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 280059119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 280159119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 280259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2809076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2810076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2814