SurfaceFlinger.cpp revision 9c6e297271ec9af9d974242d89cfa08cb6ceaa0a
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" 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 56a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 58a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <private/surfaceflinger/SharedBufferStack.h> 59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header 61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id 62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */ 63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS 64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003 65a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif 66a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopian 7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 82cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending(false), 83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole(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); 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t textureData[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, 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 291ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 292ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.open(); 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 300a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 301a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 3028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent() 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 314f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 315f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t timeout = -1; 3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t freezeDisplayTimeout = ms2ns(5000); 317f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (UNLIKELY(isFrozen())) { 318f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // wait 5 seconds 319f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t now = systemTime(); 320f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mFreezeDisplayTime == 0) { 321f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mFreezeDisplayTime = now; 322f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian timeout = waitTime>0 ? waitTime : 0; 325bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project } 326f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 327bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 3280408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3290408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // see if we timed out 3300408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (isFrozen()) { 3310408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t now = systemTime(); 3320408772e34931351d062f2088b611325ddaa6cdbMathias Agopian nsecs_t frozenTime = (now - mFreezeDisplayTime); 3330408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (frozenTime >= freezeDisplayTimeout) { 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we timed out and are still frozen 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay, mFreezeCount); 3370408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = 0; 339bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplay = false; 3400408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3410408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3430408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (msg != 0) { 3440408772e34931351d062f2088b611325ddaa6cdbMathias Agopian switch (msg->what) { 3450408772e34931351d062f2088b611325ddaa6cdbMathias Agopian case MessageQueue::INVALIDATE: 3460408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // invalidate message, just return to the main loop 3470408772e34931351d062f2088b611325ddaa6cdbMathias Agopian return; 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() { 354f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mEventQueue.invalidate(); 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 357582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 359134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 362134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 367134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 368582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 369582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 370582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 371582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 372582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 373134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 374134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 375134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 376134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 377582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 378582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 379134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 380134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 381134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 382134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 383134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 384134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 385134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 386134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 387582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 388582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 389582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 390582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 391582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 392134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 393134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 394134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 395134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 396134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 397134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 398bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 399bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 401bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return mEventQueue.postMessage(msg, reltime, flags); 402bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 403bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 404bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 405bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 406bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 407bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime, flags); 408bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (res == NO_ERROR) { 409bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian msg->wait(); 410bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 411bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // check for transactions 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mConsoleSignals)) { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleConsoleEvents(); 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // if we're in a global transaction, don't do anything. 430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (UNLIKELY(transactionFlags)) { 433698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian handleTransaction(transactionFlags); 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // post surfaces (if needed) 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handlePageFlip(); 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 439a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (UNLIKELY(mHwWorkListDirty)) { 440a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // build the h/w work list 441a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian handleWorkList(); 442a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 443a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 4458a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian if (LIKELY(hw.canDraw() && !isFrozen())) { 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // repaint the framebuffer (if needed) 44735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 44835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = hw.getCurrentBufferIndex(); 44935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog& logger(GraphicLog::getInstance()); 45035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 45135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT, index); 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleRepaint(); 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian // inform the h/w that we're done compositing 45535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 45674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian hw.compositionComplete(); 45774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 45835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 4598392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala postFramebuffer(); 4608392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala 46135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT_DONE, index); 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pretend we did the post 464e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project usleep(16667); // 60 fps period 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (!mSwapRegion.isEmpty()) { 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 4749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 4759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = now; 4760656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 4779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime = systemTime() - now; 4789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = 0; 4790656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.clear(); 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents() 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something to do with the console 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int what = android_atomic_and(0, &mConsoleSignals); 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleAcquired) { 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.acquireScreen(); 4919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // this is a temporary work-around, eventually this should be called 4929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager 493abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49659119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (mDeferReleaseConsole && hw.isScreenAcquired()) { 49762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // We got the release signal before the acquire signal 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = false; 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleReleased) { 50359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (hw.isScreenAcquired()) { 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = true; 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 569c08731e756868653d09d3e49b723706df3687070Mathias Agopian const uint32_t type = mCurrentState.orientationType; 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freezing or unfreezing the display -> trigger animation if needed 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay = mCurrentState.freezeDisplay; 587064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian if (mFreezeDisplay) 588064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian mFreezeDisplayTime = 0; 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5910aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5920aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5970aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5980aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 59948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 6010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 6023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 6033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 6050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 6060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 6075d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 6080aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 6090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const 617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 6221bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 641970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 664970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 665a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 666970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 685ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 702a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 713a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 7278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 732970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 738970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 739970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 740970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 741970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 750cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = false; 751cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool visibleRegions = mVisibleRegionsDirty; 7571bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegions |= lockPageFlip(currentLayers); 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region screenRegion(hw.bounds()); 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (visibleRegions) { 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7691bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 7704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7714da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7764da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 779ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 786ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 787ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 788ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 789ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 790ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 795076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 797b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 815a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 816a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 817a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 818a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 819a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 820a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 821a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 822a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 82345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 82653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 82773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 82873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 82973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 830a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 836b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8370656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mDebugRegion)) { 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 843b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 844b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 845b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 8498b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 8508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 851df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 856b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 85729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 8580656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 86129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 86429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 86695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 86729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 868df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 86995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 87029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 8710656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 87329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 8750656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8799c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian setupHardwareComposer(mDirtyRegion); 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8829c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 8839c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopianvoid SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 889f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 890f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 891f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 892f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!cur) { 8939c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 8964da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 898a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 899f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian LOGE_IF(hwc.getNumLayers() != count, 90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 902a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 90424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 90524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 90624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 907a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 912f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 913f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 914f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian layer->setPerFrameData(&cur[i]); 915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9169c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 917f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 918f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 919f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 920f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (err == NO_ERROR) { 9219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // what's happening here is tricky. 9229c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we want to clear all the layers with the CLEAR_FB flags 9239c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that are opaque. 9249c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // however, since some GPU are efficient at preserving 9259c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the backbuffer, we want to take advantage of that so we do the 9269c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // clear only in the dirty region (other areas will be preserved 9279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // on those GPUs). 9289c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // NOTE: on non backbuffer preserving GPU, the dirty region 9299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // has already been expanded as needed, so the code is correct 9309c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // there too. 9319c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // However, the content of the framebuffer cannot be trusted when 9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we switch to/from FB/OVERLAY, in which case we need to 9349c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // expand the dirty region to those areas too. 9359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Note also that there is a special case when switching from 9379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // "no layers in FB" to "some layers in FB", where we need to redraw 9389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // the entire FB, since some areas might contain uninitialized 9399c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // data. 9409c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // 9419c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Also we want to make sure to not clear areas that belong to 9429c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // layers above that won't redraw (we would just erasing them), 9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // that is, we can't erase anything outside the dirty region. 944a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian Region transparent; 946f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 9479c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { 9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.set(hw.getBounds()); 9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut = transparent; 9509c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } else { 9519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian for (size_t i=0 ; i<count ; i++) { 9529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian const sp<LayerBase>& layer(layers[i]); 9539c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { 9549c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.orSelf(layer->visibleRegionScreen); 9559c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9569c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); 9579c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (isOverlay != layer->isOverlay()) { 9589c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // we transitioned to/from overlay, so add this layer 9599c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // to the dirty region so the framebuffer can be either 9609c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // cleared or redrawn. 9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian dirtyInOut.orSelf(layer->visibleRegionScreen); 9629c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian } 9639c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian layer->setOverlay(isOverlay); 964f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 9659c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // don't erase stuff outside the dirty region 9669c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian transparent.andSelf(dirtyInOut); 967f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian /* 970f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian * clear the area of the FB that need to be transparent 971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian */ 972f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (!transparent.isEmpty()) { 973f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClearColor(0,0,0,0); 974f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator it = transparent.begin(); 975f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian Region::const_iterator const end = transparent.end(); 976f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const int32_t height = hw.getHeight(); 977f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian while (it != end) { 978f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Rect& r(*it++); 979f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const GLint sy = height - (r.top + r.height()); 980f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 982f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian } 983a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 984a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 985f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian if (UNLIKELY(!mWormholeRegion.isEmpty())) { 990f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // should never happen unless the window manager has a bug 991f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian // draw something... 992f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian drawWormhole(); 993f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 99445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 995f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 996f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 997f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 99845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 99945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 100045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 100145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 1002f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1003f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian size_t count = layers.size(); 100445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { 1006f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian continue; 100745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 100845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 100945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 101045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 101145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 101245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 101345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10180a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 10190a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 102053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10210656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 102253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 102353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 10260a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 10300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10380926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 104520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 104620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 104720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 104953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 105053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 105153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 105253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10570a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10580656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10610a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!mDebugBackground)) { 10800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 108120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 108220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 108320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 108420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 10967f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external) 10971f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (GLExtensions::getInstance().haveTextureExternal()) { 10981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 10991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 11000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif 1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 110720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 110820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 110920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 111020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1116a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 1117ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glLoadIdentity(); 1118ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glMatrixMode(GL_MODELVIEW); 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mFrameCount; 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mLastFrameCount = 0; 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static nsecs_t mLastFpsTime = 0; 1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static float mFps = 0; 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameCount++; 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t now = systemTime(); 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t diff = now - mLastFpsTime; 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (diff > ms2ns(250)) { 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFpsTime = now; 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFrameCount = mFrameCount; 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: mFPS has the value we want 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1139076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1147076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1149f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 115396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 115496f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 115696f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11574f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11584f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11594f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 116096f0819f81293076e652792794a961543e6750d7Mathias Agopian 116196f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 116296f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 116396f0819f81293076e652792794a961543e6750d7Mathias Agopian 11644f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 116596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 116696f0819f81293076e652792794a961543e6750d7Mathias Agopian 116796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 116896f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 116996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 117096f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 117196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 117296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 117396f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1178b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11800d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1181b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1184076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11873d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 119276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 119376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 119576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 119676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 119776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11988c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11990b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian layerBase->onRemoved(); 12000b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 12013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 12023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 120396f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 120496f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 12059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 12069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 12079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 120896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 121096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 121196f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 121296f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1215dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1216dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1217dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1218dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1219dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1225bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 1229bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian signalEvent(); 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1235698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) { 1236698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1237cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian uint32_t flags = 0; 1239698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1240698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1241698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1242698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1243698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= setClientStateLocked(client, s.state); 1244698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1245698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (flags) { 1246698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian setTransactionFlags(flags); 1247698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1248698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1249698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian signalEvent(); 1250698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1251698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // if there is a transaction with a resize, wait for it to 1252698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // take effect before returning. 1253698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian while (mResizeTransationPending) { 1254698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1256698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // just in case something goes wrong in SF, return to the 1257698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // called after a few seconds. 1258698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1259698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mResizeTransationPending = false; 1260698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian break; 1261cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 1; 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 127562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 0; 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 128962b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy, 1294c08731e756868653d09d3e49b723706df3687070Mathias Agopian int orientation, uint32_t flags) 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != orientation) { 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1302c08731e756868653d09d3e49b723706df3687070Mathias Agopian mCurrentState.orientationType = flags; 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation = orientation; 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCV.wait(mStateLock); 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project orientation = BAD_VALUE; 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return orientation; 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13130ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 13140ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13150ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 13160ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1320076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1321a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 13226e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 13236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 13246e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 13256e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 13266e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 13276e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 13288b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1330b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1333a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1334a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 13371293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 13381293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 134096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1344076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 134596f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1346285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 134796f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 13508b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 135196f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1352a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1353b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1354b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1355a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1356b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 13571c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1358b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 135996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1365b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1366f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 136796f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 13681c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1377a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1378a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1379a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 13808f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1381a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1385a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1386a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1387a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1388a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1389a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 139096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1391f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 139296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (LIKELY(err != NO_ERROR)) { 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1394076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1399b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1400f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 140196f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 140396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 14099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 14109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 14119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 14129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 14138b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 14140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 14150aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 14160aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 14179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 14189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 141948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 14200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 142196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 142248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 142348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 142448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 142548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 142648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 14279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 14289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 14299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 14309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1431ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1433759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1434ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1435ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1436ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1437ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1438ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1439ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1440ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1441ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1442ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1443ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1444ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian LOGE_IF(idx < 0, 1445ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1446f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1447ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian LOGE_IF(err<0 && err != NAME_NOT_FOUND, 1448ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1449ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1450ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1453698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 145496f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1455698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1458698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1459698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1460698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1461698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1462698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1463698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1464698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1465698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1466698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1467698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1468698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1469698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1470698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1471698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1472698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1474698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1475698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1476698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1477698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1478698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mResizeTransationPending = true; 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1481698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1482698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1483698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1484698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1485698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1486698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1487698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1488698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1489698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1490698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1491698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1492698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1493698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1494698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1495698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1496698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1498698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15171d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 152099b49840d309727678b77403d6cc9f920111623fMathias Agopian 152199b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // figure out if we're stuck somewhere 15309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 15359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15458b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 155148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 155248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump the visible layer list 155348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 155648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 155748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 15591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 15601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian layer->dump(result, buffer, SIZE); 15611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const Layer::State& s(layer->drawingState()); 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.transparentRegion.dump(result, "transparentRegion"); 1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 156748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 156848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump the layers in the purgatory 156948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 157048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 157148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 157248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 157348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 157448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 157548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 157648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian layer->shortDump(result, buffer, SIZE); 157748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 157848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 157948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 158048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump SurfaceFlinger global state 158148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 158248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 1583ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 158448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian result.append(buffer); 1585ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 1586ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 1587ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 1588ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getVendor(), 1589ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getRenderer(), 1590ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian extensions.getVersion()); 1591ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian result.append(buffer); 1592ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 1593ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian result.append(buffer); 1594ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion.dump(result, "WormholeRegion"); 1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, 1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay?"yes":"no", mFreezeCount, 1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation, hw.canDraw()); 1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 16029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 16039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last eglSwapBuffers() time: %f us\n" 16049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last transaction time : %f us\n", 16059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); 16069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 16089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inSwapBuffersDuration || !locked) { 16099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 16109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inSwapBuffersDuration/1000.0); 16119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 16149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inTransactionDuration || !locked) { 16159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 16169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inTransactionDuration/1000.0); 16179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 162048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 162148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump HWComposer state 162248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 162373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 162473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 162573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 162653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 162773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian result.append(buffer); 162822da60c3e64cd57535cbba063c07127814a2b52fMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 162973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 163048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian /* 163148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian * Dump gralloc state 163248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian */ 16333330b203039dea366d4981db1408a460134b2d2cMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1634076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian alloc.dump(result); 16351d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling hw.dump(result); 16369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 16379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (locked) { 16389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mStateLock.unlock(); 16399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project write(fd, result.string(), result.size()); 1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1650698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case FREEZE_DISPLAY: 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case UNFREEZE_DISPLAY: 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 165559119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 16569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1661a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 166299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 166399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1664375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1665375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1666375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 16691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 16701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 16711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 16721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 16731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 16741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 16751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 167699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 167799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 16781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian LOGE("Permission Denial: " 16791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 16801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 16811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 16821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1688b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 168999b49840d309727678b77403d6cc9f920111623fMathias Agopian if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1690375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1691375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1692375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1693375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1694375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 169901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 170035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 170553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 170653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 171353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1714cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1715cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1716cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1717cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1718cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 172035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1006:{ // enable/disable GraphicLog 172135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int enabled = data.readInt32(); 172235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog::getInstance().setEnabled(enabled); 172335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return NO_ERROR; 172435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian } 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1007: // set mFreezeCount 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = data.readInt32(); 17270408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 172953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 173053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 173153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 173253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 173353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 173453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1735a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1736a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1737a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1738a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1739a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1740a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 174201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 175853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 175953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian Mutex::Autolock _l(mStateLock); 176053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 176153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe 176253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian signalEvent(); 176353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 176453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 176559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 176659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 176959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 177059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 177159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 177259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 177359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 177459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 177559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 177659119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 177759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 177859119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 177959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 178059119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 178159119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 178259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 178459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 178559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 178659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 178959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1790015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 179159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 179259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 179559119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 179759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 179859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 179959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 180259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 181759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 182359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 182559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 182959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 184559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1847ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian const GLfloat texCoords[4][2] = { {0,1}, {0,1-v}, {u,1-v}, {u,1} }; 18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1856ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1857ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1858ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1859ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1860ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1861ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1862ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1863ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1864ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1865ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1866ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1867ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1868ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1869ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1870ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1871ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1896ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1897ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1898ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1899ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 190859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1914ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1915ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1916ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1917ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 1922ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 1923ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 1924ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 1925ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 1926ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 1927ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 196259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 196359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 1986a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2074a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2075a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2093a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 210259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 210459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 212459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 212959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2130a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 213159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2137abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21447ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 21457ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 21467ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 21477ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 21487ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 21497ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2150abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2151abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2152abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2153abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2154abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2155abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2156abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 2157abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2158abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 2159abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2160abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2161015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(false); 2162015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 216359119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 216459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 216559119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 216659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 216759119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 216859119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2169abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 217059119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 217159119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2172abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2173abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 217459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 217559119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 217659119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 217759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 217859119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 217959119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2180abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 218159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 218359119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 218459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2185abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 218659119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 218759119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 218859119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2193abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 219459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 219559119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 219659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 219759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2200abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2207abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2208abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2209abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2210015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(true); 2211a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2212a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2213a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 2214a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian signalEvent(); 2215a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2216015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2223abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2226abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2227abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2234abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2239abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 224574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2248bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2249bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 225074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 225174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 225374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 225474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 225574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 225674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 22577a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis // make sure none of the layers are protected 22580abe83a680d1f410c28b755eb4b3d6bee30c39ddMathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 22597a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis const size_t count = layers.size(); 22607a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis for (size_t i=0 ; i<count ; ++i) { 22617a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis const sp<LayerBase>& layer(layers[i]); 2262b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2263b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2264b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2265b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2266b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (layer->isProtected()) { 2267b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian return INVALID_OPERATION; 2268b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 22697a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis } 22707a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis } 22717a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis } 22727a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis 227374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 227474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 227574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 227674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 227874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 227974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 228074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 228174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 228274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 228374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 228474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 228574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 228674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 228774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 22881c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 22891c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2290c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 229174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 229274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 229374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 229474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 229574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 229774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 229874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 229974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 230074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 230174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 230274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 230374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 230474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2305c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 230674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 230774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 230874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 230974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 2310f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian glScissor(0, 0, sw, sh); 2311ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 231274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 231374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 231474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2315ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 231674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 231774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 231874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 231974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 232074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2321f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 232274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 232374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2324b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2325b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2326b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2327b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2328b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2329b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 233174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 233274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 233374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 2334ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glEnable(GL_SCISSOR_TEST); 233574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 233674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 234074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 234174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 234374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 234474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 234874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 236674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 236774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 236874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2374e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2375e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2376e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 23771c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2378c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 23841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2386bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2387bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 23881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 23891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 23901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 23911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 23921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 23941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 23951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 23971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 23981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 23991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 24001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 24011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 24021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2405bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2406bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 24071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 24081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 24091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2411bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2412bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2414bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2415bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2416bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 24171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 24181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 24201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 24211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 24231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 24241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 24261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 24271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 24281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2430bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 24311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 24331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 24351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2437bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 24381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 24391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 24401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 24411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 24431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 24441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 24461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2449b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2450b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2451b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2452b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2453b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 24547303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2455b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 245696f0819f81293076e652792794a961543e6750d7Mathias Agopian 2457b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2458b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2459b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 246296f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 246396f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 246496f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 246596f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 246696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 246796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 246896f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 246996f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 247396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2474b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 24774f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24794f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 24804f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = mNameGenerator++; 248196f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 248296f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2485b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 248696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 24874f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 248896f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 248996f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 249096f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 249196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 249296f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 249396f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 249496f0819f81293076e652792794a961543e6750d7Mathias Agopian } 249596f0819f81293076e652792794a961543e6750d7Mathias Agopian } 249696f0819f81293076e652792794a961543e6750d7Mathias Agopian} 24974f113740180b6512b43723c4728f262882dc9b45Mathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const 24984f113740180b6512b43723c4728f262882dc9b45Mathias Agopian{ 24994f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mLock); 2500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 25014f113740180b6512b43723c4728f262882dc9b45Mathias Agopian wp<LayerBaseClient> layer(mLayers.valueFor(i)); 250296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 250396f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 250496f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2505076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2506076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::onTransact( 2511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{ 2513a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // these must be checked 2514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int pid = ipc->getCallingPid(); 2516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int uid = ipc->getCallingUid(); 2517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const int self_pid = getpid(); 2518a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2519a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // we're called from a different process, do the real check 252099b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2521a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE("Permission Denial: " 2523a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2524a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return PERMISSION_DENIED; 2525a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2526a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 2527a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2529a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 2530a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 253196f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 25320ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 2533b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2534b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2538a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * createSurface must be called from the GL thread so that it can 2539a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian * have access to the GL context. 2540b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2541b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class MessageCreateSurface : public MessageBase { 2543a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> result; 2544a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian SurfaceFlinger* flinger; 2545a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params; 2546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian Client* client; 2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name; 2548a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display; 2549a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w, h; 2550a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormat format; 2551a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags; 2552a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2553a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian MessageCreateSurface(SurfaceFlinger* flinger, 2554a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian ISurfaceComposerClient::surface_data_t* params, 2555a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const String8& name, Client* client, 2556a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2557a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t flags) 2558a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : flinger(flinger), params(params), client(client), name(name), 2559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display(display), w(w), h(h), format(format), flags(flags) 2560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian { 2561579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2562a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> getResult() const { return result; } 2563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual bool handler() { 2564a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian result = flinger->createSurface(params, name, client, 2565a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian display, w, h, format, flags); 2566a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 2567b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 2569b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2571a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params, name, this, display, w, h, format, flags); 2572a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFlinger->postMessageSync(msg); 2573a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2574b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2575a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 2576a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mFlinger->removeSurface(this, sid); 2577b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 25829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 25849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2586d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 25879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 25889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2589d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2590a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2591d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2592d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2593d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2594a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 25979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 25989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 25999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 26009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 26019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 26039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 26182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 26222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 26232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 26242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 26262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 26272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 26282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 26302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 26312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 26322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 26332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 26342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 26352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 26362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 26372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 26382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 26542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2662eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2663eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2666eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2667eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2669eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2672eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2675eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2680eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 26882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 26902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 26912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 26922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 26932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 26942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2696eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2697eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2698eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2699eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2700eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2702eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 27030d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 27042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 271259119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 271359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 271459119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 271559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2720076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2721076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2722076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2723076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2727