SurfaceFlinger.cpp revision d5e4ef9e439317e2525a51106dbc509d3982de24
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 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 413330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h> 4235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h> 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h> 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 508afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h" 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 53118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 57a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h> 60a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header 62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id 63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */ 64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS 65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003 66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif 67a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopian 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 83cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending(false), 84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 87a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay(false), 89abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount(0), 91bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplayTime(0), 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground(0), 948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 1013330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mConsoleSignals(0), 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("SurfaceFlinger is starting"); 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = atoi(value); 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 12778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugRegion, "showupdates enabled"); 12878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugBackground, "showbackground enabled"); 1298afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian LOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1427e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 14596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 14696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 14796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 14896f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1569a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1579a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 158b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 1768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1773330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 1811f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 187a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.stop", "bootanim"); 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian{ 1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // the window manager died on us. prepare its eulogy. 1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // unfreeze the screen in case it was... frozen 1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian mFreezeDisplayTime = 0; 1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian mFreezeCount = 0; 1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian mFreezeDisplay = false; 1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // reset screen orientation 2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian setOrientation(0, eOrientationDefault, 0); 2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // restart the boot-animation 2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian property_set("ctl.start", "bootanim"); 2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian} 2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef() 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Wait for the main thread to be done with its initialization 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.wait(); 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI( "SurfaceFlinger's main thread ready to run. " 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2698b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 2789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 2959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 2969575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 301ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 302ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.open(); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 310a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 311a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 3128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent() 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 325f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t timeout = -1; 3260408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t freezeDisplayTimeout = ms2ns(5000); 327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (UNLIKELY(isFrozen())) { 328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // wait 5 seconds 329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t now = systemTime(); 330f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mFreezeDisplayTime == 0) { 331f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mFreezeDisplayTime = now; 332f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 333f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 334f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian timeout = waitTime>0 ? waitTime : 0; 335bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project } 336f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 3380408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3390408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // see if we timed out 3400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (isFrozen()) { 3410408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t now = systemTime(); 3420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian nsecs_t frozenTime = (now - mFreezeDisplayTime); 3430408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (frozenTime >= freezeDisplayTimeout) { 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we timed out and are still frozen 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay, mFreezeCount); 3470408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = 0; 349bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplay = false; 3500408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3510408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3520408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3530408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (msg != 0) { 3540408772e34931351d062f2088b611325ddaa6cdbMathias Agopian switch (msg->what) { 3550408772e34931351d062f2088b611325ddaa6cdbMathias Agopian case MessageQueue::INVALIDATE: 3560408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // invalidate message, just return to the main loop 3570408772e34931351d062f2088b611325ddaa6cdbMathias Agopian return; 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() { 364f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mEventQueue.invalidate(); 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 367582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 368582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 369134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 370582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 371134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 372134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 377134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 379582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 380582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 381582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 382582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 386134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 387582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 388582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 389134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 390134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 391134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 392134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 393134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 394134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 395134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 396134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 397582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 398582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 399582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 400582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 401582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 402134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 403134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 404134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 405134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 406134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 407134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 409bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return mEventQueue.postMessage(msg, reltime, flags); 412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 413bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 414bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 415bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 416bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 417bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime, flags); 418bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (res == NO_ERROR) { 419bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian msg->wait(); 420bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 421bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // check for transactions 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mConsoleSignals)) { 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleConsoleEvents(); 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // if we're in a global transaction, don't do anything. 440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (UNLIKELY(transactionFlags)) { 443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian handleTransaction(transactionFlags); 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // post surfaces (if needed) 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handlePageFlip(); 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4493a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian if (mDirtyRegion.isEmpty()) { 4503a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // nothing new to do. 4513a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian return true; 4523a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian } 4533a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 454a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (UNLIKELY(mHwWorkListDirty)) { 455a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // build the h/w work list 456a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian handleWorkList(); 457a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 458a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 460a44b04163957d6086362f6f365443c4c93379031Mathias Agopian if (LIKELY(hw.canDraw())) { 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // repaint the framebuffer (if needed) 46235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 46335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = hw.getCurrentBufferIndex(); 46435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog& logger(GraphicLog::getInstance()); 46535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 46635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT, index); 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleRepaint(); 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46974faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian // inform the h/w that we're done compositing 47035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 47174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian hw.compositionComplete(); 47274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 47335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 4748392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala postFramebuffer(); 4758392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala 47635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT_DONE, index); 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pretend we did the post 479e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project usleep(16667); // 60 fps period 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4873a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // this should never happen. we do the flip anyways so we don't 4883a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // risk to cause a deadlock with hwc 4893a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty"); 490a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 491a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 492a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 493a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 496a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents() 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something to do with the console 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int what = android_atomic_and(0, &mConsoleSignals); 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleAcquired) { 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.acquireScreen(); 5079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // this is a temporary work-around, eventually this should be called 5089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager 509abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleReleased) { 51359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (hw.isScreenAcquired()) { 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 534ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 537ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 538ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5413d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 543ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5443d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 57721230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freezing or unfreezing the display -> trigger animation if needed 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay = mCurrentState.freezeDisplay; 595064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian if (mFreezeDisplay) 596064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian mFreezeDisplayTime = 0; 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5990aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 6000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 60748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 6103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 6113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 6130aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 6140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 6155d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 6160aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 6170aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 6301bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 645076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 649970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 672970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 674970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 698ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 710a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 713ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 720ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 721a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 722ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 723ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 724ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 726ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 7358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 746970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 747970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 748970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 749970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 758cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = false; 759cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool visibleRegions = mVisibleRegionsDirty; 7651bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegions |= lockPageFlip(currentLayers); 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region screenRegion(hw.bounds()); 770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (visibleRegions) { 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7771bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 7784da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7794da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7804da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7814da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7824da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7834da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 794ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 795ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 796ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 797ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 798ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 803076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 805b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 816076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 818b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 823a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 824a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 825a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 826a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 827a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 828a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 829a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 83145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 83245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 83345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 83453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 83573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 83673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 83773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 838a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 839a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 840a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 841b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 844b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8450656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mDebugRegion)) { 848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 851b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 852b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 853b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 854b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 8578b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 8588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 859df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 864b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 8660656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 86829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 86929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 87129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 87229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 87495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 87529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 876df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 87795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 87829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 8790656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 88129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 8830656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian setupHardwareComposer(mDirtyRegion); 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8909c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 8919c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8959c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) 896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 897f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 898f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 899f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 900f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!cur) { 9019c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 903a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9044da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 906a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian LOGE_IF(hwc.getNumLayers() != count, 90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 910a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 91224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 91324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 91424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 915a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 91745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 91945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 920f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 921f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 922f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian layer->setPerFrameData(&cur[i]); 923f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 925f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 926f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 927f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 928f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (err == NO_ERROR) { 9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // what's happening here is tricky. 9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we want to clear all the layers with the CLEAR_FB flags 9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that are opaque. 9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // however, since some GPU are efficient at preserving 9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the backbuffer, we want to take advantage of that so we do the 9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // clear only in the dirty region (other areas will be preserved 9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // on those GPUs). 9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // NOTE: on non backbuffer preserving GPU, the dirty region 9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // has already been expanded as needed, so the code is correct 9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // there too. 9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // However, the content of the framebuffer cannot be trusted when 9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we switch to/from FB/OVERLAY, in which case we need to 9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // expand the dirty region to those areas too. 9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9449c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Note also that there is a special case when switching from 9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // "no layers in FB" to "some layers in FB", where we need to redraw 9469c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the entire FB, since some areas might contain uninitialized 9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // data. 9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Also we want to make sure to not clear areas that belong to 9503a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian // layers above that won't redraw (we would just be erasing them), 9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that is, we can't erase anything outside the dirty region. 952a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian Region transparent; 954f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { 9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.set(hw.getBounds()); 9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut = transparent; 9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } else { 9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian for (size_t i=0 ; i<count ; i++) { 9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const sp<LayerBase>& layer(layers[i]); 9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { 9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.orSelf(layer->visibleRegionScreen); 9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9649c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); 9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (isOverlay != layer->isOverlay()) { 9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we transitioned to/from overlay, so add this layer 9679c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // to the dirty region so the framebuffer can be either 9689c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // cleared or redrawn. 9699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut.orSelf(layer->visibleRegionScreen); 9709c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9719c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian layer->setOverlay(isOverlay); 972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // don't erase stuff outside the dirty region 9749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.andSelf(dirtyInOut); 975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian /* 978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian * clear the area of the FB that need to be transparent 979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian */ 980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!transparent.isEmpty()) { 981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClearColor(0,0,0,0); 982f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator it = transparent.begin(); 983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator const end = transparent.end(); 984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const int32_t height = hw.getHeight(); 985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian while (it != end) { 986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Rect& r(*it++); 987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const GLint sy = height - (r.top + r.height()); 988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 990f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian } 991a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 992a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 994f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 997cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 998cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 999cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 1000cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 1001cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) { 1002f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // should never happen unless the window manager has a bug 1003f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // draw something... 1004f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian drawWormhole(); 1005f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 100645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 100745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 100845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 100945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 1010cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 1011f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1012f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian size_t count = layers.size(); 101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10149c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { 1015f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian continue; 101645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 101745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 101845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 101945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 102045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 102145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 102245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 10280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 102953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10300656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 103153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 103253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 10360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 10390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1041c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1042c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 105520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 105620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 105720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 105953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 106053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 106153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 106253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10670a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10680656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10710a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!mDebugBackground)) { 10870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 108820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 108920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 109020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 109120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1100c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1104c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1105c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1111c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1112c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 1113c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian 1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 111520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 111620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 111720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 111820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1124a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 1125ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glLoadIdentity(); 1126ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glMatrixMode(GL_MODELVIEW); 1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mFrameCount; 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mLastFrameCount = 0; 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static nsecs_t mLastFpsTime = 0; 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static float mFps = 0; 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameCount++; 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t now = systemTime(); 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t diff = now - mLastFpsTime; 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (diff > ms2ns(250)) { 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFpsTime = now; 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFrameCount = mFrameCount; 1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: mFPS has the value we want 1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1147076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1155076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1157f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 116196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 116296f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 116496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11654f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11664f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11674f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 116896f0819f81293076e652792794a961543e6750d7Mathias Agopian 116996f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 117096f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 117196f0819f81293076e652792794a961543e6750d7Mathias Agopian 11724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 117396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 117496f0819f81293076e652792794a961543e6750d7Mathias Agopian 117596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 117696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 117796f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 117896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 117996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 118096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 118196f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1184076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1186b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1187b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11880d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1189b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1192076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 120076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 120176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 12029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 120376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 120476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 120576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 12068c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 12070b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian layerBase->onRemoved(); 12080b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 12093d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 12103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 121196f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 121296f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 12139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 12149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 12159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 121696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 121896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 121996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 122096f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1223dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1224dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1225dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1226dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1227dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1233bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 1237bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian signalEvent(); 1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1243b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 1244b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis int orientation) { 1245698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1246cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 1247698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian uint32_t flags = 0; 1248b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1249b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1250b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 1251b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis flags |= eTransactionNeeded; 1252b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mResizeTransationPending = true; 1253b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 1254b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis LOGW("setTransactionState: ignoring unrecognized orientation: %d", 1255b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1256b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1257b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1258b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1259698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1260698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1261698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1262698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1263698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= setClientStateLocked(client, s.state); 1264698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1265698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (flags) { 1266698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian setTransactionFlags(flags); 1267698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1268698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1269698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian signalEvent(); 1270698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1271698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // if there is a transaction with a resize, wait for it to 1272698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // take effect before returning. 1273698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian while (mResizeTransationPending) { 1274698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1275698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1276698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // just in case something goes wrong in SF, return to the 1277698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // called after a few seconds. 1278698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1279698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mResizeTransationPending = false; 1280698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian break; 1281cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 1; 1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 129562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 0; 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 130962b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13138b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy, 1314c08731e756868653d09d3e49b723706df3687070Mathias Agopian int orientation, uint32_t flags) 1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != orientation) { 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 132221230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown mCurrentState.orientationFlags = flags; 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation = orientation; 1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCV.wait(mStateLock); 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project orientation = BAD_VALUE; 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return orientation; 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13330ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 13340ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 13360ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1340076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1341a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 13426e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 13436e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 13446e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 13456e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 13466e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 13476e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 13488b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1350b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1353a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1354a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 13571293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 13581293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 136096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1362118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1363118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1364118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1367076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 136896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1369285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 137096f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1371b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 13738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 137496f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1375a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1376b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1377b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1378a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1379b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 13801c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1381b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 138296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1388b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1389f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 139096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 13911c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1400a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1401a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1402a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 14038f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1404a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1408a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1409a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1410a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1411a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1412a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 141396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1414f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 141596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (LIKELY(err != NO_ERROR)) { 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1417076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1422b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1423f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 142496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 142696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1427118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1428118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1429118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1430118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1431118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1432118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1433118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1434118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1435118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t err = layer->capture(); 1436118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian if (err != NO_ERROR) { 1437118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer.clear(); 1438118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian LOGW("createScreenshotSurface failed (%s)", strerror(-err)); 1439118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 144396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 14449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 14459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 14469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 14479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 14488b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 14490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 14500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 14510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 14529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 14539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 145448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 14550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 145696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 145748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 145848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 145948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 146048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 146148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 14629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 14639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 14649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 14659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1466ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1468759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1469ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1470ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1471ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1472ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1473ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1474ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1475ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1476ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1477ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1478ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1479ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian LOGE_IF(idx < 0, 1480ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1481f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1482ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian LOGE_IF(err<0 && err != NAME_NOT_FOUND, 1483ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1484ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1485ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1488698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 148996f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1490698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1493698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1494698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1495698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1497698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1498698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1499698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1500698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1501698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1502698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1503698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1504698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1505698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1506698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1507698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1509698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1510698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1511698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1512698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1513698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mResizeTransationPending = true; 1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1516698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1517698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1518698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1519698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1520698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1521698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1522698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1523698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1524698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1525698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1526698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1527698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1528698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1529698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1530698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1531698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1533698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15521d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 155599b49840d309727678b77403d6cc9f920111623fMathias Agopian 155699b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // figure out if we're stuck somewhere 15659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 15669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 15679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 15689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 15699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 15709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15808b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 158648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 158748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump the visible layer list 158848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 159148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 159248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 15941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 15951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian layer->dump(result, buffer, SIZE); 15961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const Layer::State& s(layer->drawingState()); 1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.transparentRegion.dump(result, "transparentRegion"); 1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 160248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 160348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump the layers in the purgatory 160448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 160548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 160648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 160748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 160848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 160948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 161048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 161148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian layer->shortDump(result, buffer, SIZE); 161248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 161348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 161448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 161548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump SurfaceFlinger global state 161648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 161748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 1618ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 161948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 1620ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 1621ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 1622ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 1623ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getVendor(), 1624ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getRenderer(), 1625ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getVersion()); 1626ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian result.append(buffer); 1627ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 1628ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian result.append(buffer); 1629ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion.dump(result, "WormholeRegion"); 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, 1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay?"yes":"no", mFreezeCount, 1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation, hw.canDraw()); 1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 16379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 16389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last eglSwapBuffers() time: %f us\n" 1639d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian " last transaction time : %f us\n" 1640d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian " refresh-rate : %f fps\n" 1641d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian " x-dpi : %f\n" 1642d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian " y-dpi : %f\n", 1643d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian mLastSwapBufferTime/1000.0, 1644d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian mLastTransactionTime/1000.0, 1645d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian hw.getRefreshRate(), 1646d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian hw.getDpiX(), 1647d5e4ef9e439317e2525a51106dbc509d3982de24Mathias Agopian hw.getDpiY()); 16489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 16509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inSwapBuffersDuration || !locked) { 16519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 16529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inSwapBuffersDuration/1000.0); 16539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 16569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inTransactionDuration || !locked) { 16579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 16589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inTransactionDuration/1000.0); 16599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 166248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 166348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump HWComposer state 166448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 166573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 166673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 166773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 166853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 166973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian result.append(buffer); 167022da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 167173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 167248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 167348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump gralloc state 167448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 16753330b203039dea366d4981db1408a460134b2d2cMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1676076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian alloc.dump(result); 16771d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling hw.dump(result); 16789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 16799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (locked) { 16809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mStateLock.unlock(); 16819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project write(fd, result.string(), result.size()); 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1692698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case FREEZE_DISPLAY: 1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case UNFREEZE_DISPLAY: 1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 169759119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 16989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1703a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 170499b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 170599b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1706375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1707375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1708375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 17111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 17131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 17141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 17151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 171899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 171999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 17201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian LOGE("Permission Denial: " 17211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1730b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 173199b49840d309727678b77403d6cc9f920111623fMathias Agopian if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1732375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1733375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1734375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1735375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1736375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 174101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 174235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 174753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 174853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 175553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1756cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1757cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1758cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1759cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1760cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 176235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1006:{ // enable/disable GraphicLog 176335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int enabled = data.readInt32(); 176435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog::getInstance().setEnabled(enabled); 176535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return NO_ERROR; 176635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian } 1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1007: // set mFreezeCount 1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = data.readInt32(); 17690408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 177153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 177253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 177353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 177453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 177553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 177653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1777a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1779a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1780a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1781a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1782a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 178401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 180053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 180153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian Mutex::Autolock _l(mStateLock); 180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18033a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian mDirtyRegion.set(hw.bounds()); 180453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian signalEvent(); 180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 180759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 180859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1809118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1810118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1811118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1812118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1813118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1814118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1815118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 181859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 181959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 182059119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 182259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 182359119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 182459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 182559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 182659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 182759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 182859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 182959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 183059119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 183159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 183459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 183559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1839015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 184159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 184459119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 184559119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 184659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 184759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 184859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 185159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1853c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1854c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1857a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1858a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1866118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1867118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 187859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 188059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1887a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1891118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 189559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1897a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1906ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1907ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1908ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1909ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1910ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1911ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1912ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1913ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1914ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1915ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1916ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1917ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1918ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1919ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1920ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1921ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1946ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1947ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1948ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1949ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 195859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1964ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1965ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1966ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1967ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 1972ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 1973ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 1974ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 1975ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 1976ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 1977ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 1983a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 1984a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 1985a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 1986a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1987a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 1988a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 200159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2042a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2043c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 209659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2127a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2128a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2146a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 215559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 215759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 217759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 217859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2183a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2184c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 218559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2191abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21987ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 21997ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 22007ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 22017ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 22027ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 22037ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2204abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2205abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2206abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2207abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2208abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2209abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2210abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 2211abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2212abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 2213abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2214abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2215015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 221659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 221759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 221859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 222059119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 222159119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2222abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 222359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 222459119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2225abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2226abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 222759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 222859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 222959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 223059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 223159119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 223259119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2233abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 223459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 223559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 223659119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 223759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2238abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 223959119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 224059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 224159119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2246abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 224759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 224859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 224959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 225059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2260abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2261abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2262abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2263a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2264a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2265a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 2266a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian signalEvent(); 2267a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2268015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2275abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2278abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2279abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2286abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2291abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2300bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2301bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 230574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 231074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 231174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 231574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 232174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23241c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 23251c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2326c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 232774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 232874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 232974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 233074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 233474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2341c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 2346f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian glScissor(0, 0, sw, sh); 2347ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2351ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2357f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 23589575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 23599575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2362b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2363b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2364b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2365b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2366b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2367b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2368bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 2372ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 237774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 238474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 239874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 240974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2412e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2413e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2414e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 24151c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2416c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 24221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2424bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2425bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 24281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 24291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 24301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 24321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 24331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 24371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2443bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2444bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 24471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2449bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2450bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2452bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2453bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2454bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 24551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 24561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 24581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 24611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 24621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 24641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 24651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 24661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2468bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 24731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2475bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 24781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 24791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 24811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2485b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2487b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2488b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2489b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2490b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2491b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 24927303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2493b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 249496f0819f81293076e652792794a961543e6750d7Mathias Agopian 2495b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2496b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2497b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 250096f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 250196f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 250296f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 250396f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 250496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 250596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 250696f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 250796f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 251196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2512b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2514076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 25154f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25174f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 25184f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = mNameGenerator++; 251996f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 252096f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2523b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 252496f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 25254f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 252696f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 252796f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 252896f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 252996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 253096f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 253196f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 253296f0819f81293076e652792794a961543e6750d7Mathias Agopian } 253396f0819f81293076e652792794a961543e6750d7Mathias Agopian } 253496f0819f81293076e652792794a961543e6750d7Mathias Agopian} 25354f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const 25364f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{ 25374f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 2538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 25394f113740180b6512b43723c4728f262882dc9b45Mathias Agopian wp<LayerBaseClient> layer(mLayers.valueFor(i)); 254096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 254196f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 254296f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact( 2549a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2550a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{ 2551a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // these must be checked 2552a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2553a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int pid = ipc->getCallingPid(); 2554a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int uid = ipc->getCallingUid(); 2555a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int self_pid = getpid(); 2556a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2557a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // we're called from a different process, do the real check 255899b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE("Permission Denial: " 2561a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return PERMISSION_DENIED; 2563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 256996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 25700ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 2571b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2572b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2575b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * createSurface must be called from the GL thread so that it can 2577a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * have access to the GL context. 2578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2580a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class MessageCreateSurface : public MessageBase { 2581a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> result; 2582a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian SurfaceFlinger* flinger; 2583a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params; 2584a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian Client* client; 2585a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name; 2586a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display; 2587a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w, h; 2588a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormat format; 2589a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags; 2590a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2591a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian MessageCreateSurface(SurfaceFlinger* flinger, 2592a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params, 2593a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name, Client* client, 2594a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags) 2596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : flinger(flinger), params(params), client(client), name(name), 2597a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display(display), w(w), h(h), format(format), flags(flags) 2598a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2599579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> getResult() const { return result; } 2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual bool handler() { 2602a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian result = flinger->createSurface(params, name, client, 2603a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display, w, h, format, flags); 2604a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 2605b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2606a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 2607b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2608a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2609a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params, name, this, display, w, h, format, flags); 2610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFlinger->postMessageSync(msg); 2611a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2612b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2613a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 2614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mFlinger->removeSurface(this, sid); 2615b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2616b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2617b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 26209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 26229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2624d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 26259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 26269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2627d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2629d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2630d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2631d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2632a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2633a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 26359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 26369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 26379a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 26389a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 26399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26409a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 26419a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 26642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 26652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 26662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 26682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 26692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 26702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 26712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 26722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 26732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 26742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 26752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 26782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 26792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 26842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 26852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 26862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 26872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 26882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 26892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 26902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 26912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 26922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 26932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2700eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2701eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2704eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2705eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2707eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2710eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2713eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2718eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 27262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 27282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 27292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 27302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 27312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 27322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2734eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2735eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2736eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2737eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2738eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2740eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 27410d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 27422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275059119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 275159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 275259119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 275359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2761076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2765