SurfaceFlinger.cpp revision ef19414bd8b77a26f5751f3845be79025a8263fe
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 26a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 39d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h> 40d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 463330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h> 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 54d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 58118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 62a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 641db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h> 6590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h> 66ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian#include <gui/BitTube.h> 67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian 8099b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8199b49840d309727678b77403d6cc9f920111623fMathias Agopian 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 90abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 94a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 993330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 107a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1153854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING 1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1215df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else 1225df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled" 1233854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif 1248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 125a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugRegion, "showupdates enabled"); 126a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian setTransactionState(state, eOrientationDefault, 0); 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 154a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1577303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1597303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1627e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 16596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 16696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16896f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 178b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 181e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 196a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1973330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 207a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 208a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 209a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 218a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI( "SurfaceFlinger's main thread ready to run. " 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 234e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 237e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2397303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 2839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 2849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 298ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 299ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 301d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 302d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 3048aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 310d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 311d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 312a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 313a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 3148b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 318a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 319a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 321a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 322a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 323a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 325d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 326582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 327582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 328134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 334134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 337582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 338582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 339582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 340582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 346582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 347582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 348134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 356582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 357582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 359582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 361134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 362134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 367d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 368d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 369d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 3708aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 371bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 372bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 37699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 37799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 37899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 38099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 38199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 38299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 38399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 38499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 38599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 38699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 38799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 38899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 38999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 39099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 39199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 39299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 39399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 39499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 39599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 39699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 39999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 40099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 40199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 40299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 40899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) 41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 4131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 41569a655caef30663403802281210363f643ceb946Mathias Agopian case MessageQueue::REFRESH: { 41669a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::INVALIDATE: { 41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we're in a global transaction, don't do anything. 41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(transactionFlags)) { 42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleTransaction(transactionFlags); 42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // post surfaces (if needed) 42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handlePageFlip(); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42769a655caef30663403802281210363f643ceb946Mathias Agopian// signalRefresh(); 42869a655caef30663403802281210363f643ceb946Mathias Agopian// 42969a655caef30663403802281210363f643ceb946Mathias Agopian// } break; 43069a655caef30663403802281210363f643ceb946Mathias Agopian// 43169a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::REFRESH: { 4323a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 433c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian handleRefresh(); 434a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 435303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 436303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 43769a655caef30663403802281210363f643ceb946Mathias Agopian// if (mDirtyRegion.isEmpty()) { 43869a655caef30663403802281210363f643ceb946Mathias Agopian// return; 43969a655caef30663403802281210363f643ceb946Mathias Agopian// } 44069a655caef30663403802281210363f643ceb946Mathias Agopian 441b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 442b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // build the h/w work list 443b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleWorkList(); 444b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian } 445303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 446b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_LIKELY(hw.canDraw())) { 447b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // repaint the framebuffer (if needed) 448b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleRepaint(); 449b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // inform the h/w that we're done compositing 450b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian hw.compositionComplete(); 451b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian postFramebuffer(); 452c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian } else { 453b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // pretend we did the post 454c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian hw.compositionComplete(); 45599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 456b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 45799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } break; 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 463841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 464b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 465b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 466b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 467b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 468b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 469a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 470a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 471a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 472a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 473e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 474e8696a40e09b24b634214684d18526187b316a2fJamie Gennis size_t numLayers = mVisibleLayersSortedByZ.size(); 475ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 476ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 477ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 478ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 479ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 480ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur); 481ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 482ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 483ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 484ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL); 485ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 486e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 487e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 488a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 489a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 490a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 495841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 496841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 497ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 498ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 499ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 500ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 501ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 502ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 503ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 504ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 505ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 506ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 507ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 508ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 509ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 510ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 511ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 512ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5193d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 530076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 55121230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 57448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5790aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5800aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5825d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5830aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 5921bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 594841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 595841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 613970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 63699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 638970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 674a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 677ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 685a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 6998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 704970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 710970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 711970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 712970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 713970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7212f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall if (!mLayersPendingRemoval.isEmpty()) { 7222f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall // Notify removed layers now that they can't be drawn from 7232f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 7242f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval[i]->onRemoved(); 7252f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7262f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.clear(); 7272f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7282f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 73028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending = false; 731cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 73799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const DisplayHardware& hw = graphicPlane(0).displayHardware(); 73899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const Region screenRegion(hw.bounds()); 73999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 7401bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 74199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const bool visibleRegions = lockPageFlip(currentLayers); 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (visibleRegions || mVisibleRegionsDirty) { 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7474da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7484da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7501bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 7514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7564da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 760ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 7640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 7650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 769ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 770ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 771ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 772ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 773ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 79099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 791076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 79999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 80199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 80299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 80399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 80499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 80599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 80699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 80799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 80899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 80999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 81099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 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); 8233e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 8243e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 8253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 8263e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 8273e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian currentLayers[i]->setGeometry(*cur); 82853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 8293e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 83073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 831a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 834b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 837841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 838841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 839b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8400656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 84299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 846b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 847b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 848b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 849b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 852a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 856a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 85895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 860df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 86195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 86229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 8630656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 86529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 8670656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 871a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian setupHardwareComposer(); 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8749c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 8759c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 879a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer() 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 881f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 882f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 8833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 8843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 8853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 8863e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 8879c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 8904da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 893e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 89445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 89545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 89824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 89924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 90024925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 901a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 9063e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 907f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 9083e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 909f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 910f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 911e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 912f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 913f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 914f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 915f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 916cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 917cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 9183e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 9193e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 920cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 921cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 9223e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 923a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 92445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 925b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 926b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 927b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 928b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 929b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 930b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 931b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 932b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 933b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 934b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 935b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 936b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 937b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 938b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 939a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 9404b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 941a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 942a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 943a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 9444b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 945a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 946a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 9473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 948a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 949a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 950a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 9513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur->getCompositionType() == HWC_OVERLAY) { 9523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 953a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 954b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 955b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 956a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian layer->clearWithOpenGL(clip); 957a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 958a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 959a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 960a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 961a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian layer->draw(clip); 9624b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 9634b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 9644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9690a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 9700a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 97153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 9720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 97353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 97453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 9750a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 976a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 9770a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 9780a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 9790a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 9800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 9810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 982c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 983c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 9870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 9880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 9890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 9900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 9910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 9920926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 99420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 99520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 99620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 99720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 99953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 100053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 100153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 100253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10070a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10080656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1020f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1021b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1022f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1023b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1024f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1025f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1026f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1027f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1028f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1029f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1030f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1031f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1032f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1033f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1034f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1035f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1036f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1037f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1038f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1039f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1040f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1043076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1051076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1053f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 10541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 10551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 10561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 105796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 105896f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 10591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 106096f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 10614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 10624f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 10634f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 106496f0819f81293076e652792794a961543e6750d7Mathias Agopian 106596f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 106696f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 106796f0819f81293076e652792794a961543e6750d7Mathias Agopian 10684f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 106996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 107096f0819f81293076e652792794a961543e6750d7Mathias Agopian 107196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 107296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 107396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 107496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 107596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 107696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 107796f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1080076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1082b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1083b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 10840d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1085b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1088076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 10959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 109676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 109776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 10989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 109976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 110076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 110176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11032f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 11040b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11063d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 110796f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 110896f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 111296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 111496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 111596f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 111696f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1119dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1120dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1121dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1122dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1123dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1129bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 113399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1139b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 114028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1141698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 114328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1144b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1145b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1146b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 114728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1148b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 114932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1150b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1151b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1152b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1153b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1154698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1155698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1156698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1157698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 115828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1159698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1160386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 116128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1162386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 116328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1164698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1165386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1166386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1167386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1168386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1169386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1170386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1171386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1172386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1173386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1174386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 117532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1176386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1177386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1178386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1179cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11830ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 11840ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 11850ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 11860ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1190076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1191a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 11926e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 11936e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1194e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 11956e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 11966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 11976e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 11988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1199ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1200b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1203a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1204a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12071293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12081293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 121096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1212118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1213118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1214118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1217076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 121896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1219285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 122096f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1221b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 12238b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 122496f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1226b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1227b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1228a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1229b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 12301c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1231b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 123296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1238b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1239f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 124096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 12411c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1250a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1251a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1252a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 12538f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1254a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1258a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1259a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1260a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1261a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1262a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 126396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1264f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 126599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1266e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1267076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1273f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 127496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 127696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1277118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1278118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1279118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1280118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1281118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1282118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1283118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1284118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 12899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 12909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 12919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 12929a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 12938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 12940aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 12950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 12960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 12979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 12989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 129948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 130196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1302b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 130348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 130448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 130548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 130648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 130748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1312ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1314759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1315ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1316ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1317ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1318ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1319ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1320ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1321ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1322ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1323ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1324ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1325e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1326ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1328e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1329ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1330ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1331ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1334698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 133596f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1336698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1339698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1340698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1341698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1342698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1343698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1344698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1345698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1346698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1347698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1348698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1349698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1350698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1351698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1352698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1353698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1355698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1356698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1357698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1358698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1361698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1362698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1363698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1367698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1370698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1371698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1372698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1374698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1375698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1376698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1377f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1378f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1379f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1380f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1382698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1385b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1386b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1387b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 13888e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 1389b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1390b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 139122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1392b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1393b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1394b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 139522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 13968acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1399b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 14008e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 1401b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1402b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 140322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1404b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1405b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1406b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1407b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1408b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 14098e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1410b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1411b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1412b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1413b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1414b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1415b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1416b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1417b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1418b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1419b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1420b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14238e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1424b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1425b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1426b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1427b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1428b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1429b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1430b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1431b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1432b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1433b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1434b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1435b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1436b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1437b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1438b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14411d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 144499b49840d309727678b77403d6cc9f920111623fMathias Agopian 144599b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 14529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 14539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 14549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 14559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 14569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 14579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 14589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 14618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 14649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 146782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 146882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 146925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 147025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 147125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 147225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 147325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 147425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 147535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 147625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 147725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 147825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 147925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 148082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 148182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 148235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 148382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 148425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 148525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 148625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 148725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 148825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 148935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 149025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 149382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 149482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 149582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 149648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 149782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 149882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 149948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 150082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 150182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 150282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 150382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 150448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 150525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 150625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 150725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 150825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 150925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 151025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 151125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 151225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 151325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 151425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 151525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 151625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 151782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 151882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 151982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 152082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 152182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 152382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 152482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 152548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 152682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 152782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 152882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 152982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 153082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 153182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 153282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 153382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 153482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 153682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 153782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 153882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1539ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 154925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 155425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 155525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 155625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 155725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 155825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 155982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 156082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 156182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 156282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 156382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 156482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 156582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 156682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 156782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1568bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 156982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 157082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 157982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1580bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1584ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 15921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 159482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 15961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 15991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 160482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1606d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian eglQueryString(graphicPlane(0).getEGLDisplay(), 160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 161173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 162282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 162382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1624c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1627b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1628b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1631c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1634b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1635b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 165482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 166682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1676698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 167959119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 16809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 16818e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 16828e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1687a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 168899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 168999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1690e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1691375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1692375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 16951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 16961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 16971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 16981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 16991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 170299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 170399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1704e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 17051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1714b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 171599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1716375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1717375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1718375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1719e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1720375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 172501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 172635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 173153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 173253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 173553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1736cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1737cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1738cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1739cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1740cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17424d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 17434d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 17444d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 17454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 174653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 174753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 174853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 174953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 175053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 175153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1752a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1753a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1754a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1755a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1756a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1757a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 175901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1762b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 176312839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 177753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 17780dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 17790dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 178099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 178153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 178253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 17830dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 17840dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 17850dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 17860dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 17870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 17880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 17890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 17900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 17910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 17920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 17930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 17940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 179559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 179659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1797118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1798118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1799118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1800118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1801118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1802118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1803118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 180659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 180722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 180822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 180959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 181059119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 181159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 181359119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 181459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 181559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 181659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 181759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 181859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 181959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 182059119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 182259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 182359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 182459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 182559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 1826a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1827a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 183059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1831015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 183659119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 183759119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 183959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 184059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 184359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1845c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1846c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1849a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1850a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 185759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1858118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1859118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1872ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 1873ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 1874ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 1875ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 1876ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 1877ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 1878ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 1879ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 1880ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 1881ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 1882ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 1883ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1884ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1885ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1886ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 1887ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 1888ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1889ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 1890ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 1891ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 1892ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1893ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 1894ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 1895ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 1896ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1897ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1898ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1899ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 1900ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1907a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 190859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1911118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 191559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1917a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1922b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1923b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1928ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1929ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1930ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1931ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1932ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1933ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1934ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1935ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1936ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1937ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1938ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1939ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1940ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1941ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1942ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1943ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1968ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1969ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1970ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1971ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 198059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1993ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 1994ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 1997ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 1998ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 1999ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2000ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2001ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2007a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2008a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2009a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2010a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2011a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2012a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2021ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2022ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2023ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2059ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2060ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2061ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2062ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2072a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2073c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2104b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2105b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 212859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2159ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2160ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2161a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2162a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2174ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2175ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2176ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2177ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2184a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 219359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2194ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2195ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2196ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 219859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 221859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 221959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 222259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2223a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2224c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 222559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2231abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 223322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 223422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22407ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 22417ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 22427ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 22437ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 22447ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 22457ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2246abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2247abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2248abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2249abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2250abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2251abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2252abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2253abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2254abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2255015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 225659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 225759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 225859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 225959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 226059119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 226159119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2262abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 226359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 226459119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2265abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2266abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 226759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 226859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 226959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 227059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 227159119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2273abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 227459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 227559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 227759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2278abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 228059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 228159119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2286abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 228759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 228859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 228959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 229059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2293abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2301abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2303a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2304a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2305a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 230699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2307a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2308015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2315abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2318abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2319abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2326abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2331abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 233774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 233874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 233974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2340bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2341bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 234274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2343fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2344fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 234574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 234674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 234774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 234899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 234974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 235074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 235274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 235374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 235574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 235674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 235774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 235874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 235974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 236074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 236174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 236274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 236374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 236474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 236574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 23669d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 23671c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2368c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 236974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 237074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 237174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 237274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 237374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 237474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 237574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 237674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2377fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 237874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 237974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 238074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 238174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 238274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2384c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 238574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 238674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 238774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 238874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 238974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 239074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2392ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 239474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 239574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 239774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2398f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 23999575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 24009575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 240274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2403b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2404b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2405b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2406b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2407b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2408b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2409bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 242274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2424fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2449e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2450e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2451e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 24529d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2453c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 24591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2461bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2462bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 24641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 246599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 24661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 24671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 24691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 24701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 24711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 24721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 24731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 24741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 24751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 24761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 24771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 247874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2480bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2481bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 24821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 24831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 24841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2486bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2487bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 24881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2489bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2490bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2491bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 24921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 24931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 24951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 24961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 24971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 24981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 24991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 25011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 25021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 250474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2505bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2512bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2522b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2524b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2525b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2527b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2528b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 25297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 253196f0819f81293076e652792794a961543e6750d7Mathias Agopian 25329a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 25339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 25359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2537d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 25389a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 25399a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2540d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2541a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2542d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2543d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2544d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2545e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2546a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2547a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 25489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 25499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 25509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 25519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 25529a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25539a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 25549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 25692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 25732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 25742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 25752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 25772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 25782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 25792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 25812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 25822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 25832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 25842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 25852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 25862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 25872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 25882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 25892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 25902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 25912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 25922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 25932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 25942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 25952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 25972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 25982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 25992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 26002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 26012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 26022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 26032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 26042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 26052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 26062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2613eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2614eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2617eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2618eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2620eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2623eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2626eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2631eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 26392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 26412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 26442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 26452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2647eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2648eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2649eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2650eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2651eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2653eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 26540d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 266359119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 266459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 266559119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 266659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2671076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2672076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2674076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2678