SurfaceFlinger.cpp revision 3094df359d1e6e2ae8ca4e935cc093f563804c96
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> 673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian#include <gui/SurfaceTextureClient.h> 68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 69bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 8099b49840d309727678b77403d6cc9f920111623fMathias Agopian 8199b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8299b49840d309727678b77403d6cc9f920111623fMathias Agopian 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 90a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 91abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 95a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 1003330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 1013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mSecureFrameBuffer(0), 1023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface(EGL_NO_SURFACE) 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 109a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1173854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING 1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1235df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else 1245df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled" 1253854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif 1268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 127a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugRegion, "showupdates enabled"); 128a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 13499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian setTransactionState(state, eOrientationDefault, 0); 15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 156a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1597303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1617303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1647e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 16796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 16896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 17096f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 180b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 198a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1993330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 2051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 2061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2071f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 209a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 210a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 211a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 220a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI( "SurfaceFlinger's main thread ready to run. " 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 236e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 239e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2408b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2427303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2698b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 2779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 2859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 2869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 2879575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 2889575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 2899575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 2909575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2919575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2929575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 2939575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 2949575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 2959575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 300ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 301ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 303d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 304d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 305d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 3068aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 312d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 313d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 314a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 315a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 3168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 321a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 322a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 323a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 324a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 325a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 327d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 328582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 331582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 334134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 335134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 339582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 340582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 341582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 342582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 343582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 344134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 345134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 346134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 347134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 349582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 355134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 356134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 357134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 358582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 359582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 360582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 361582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 362582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 363134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 364134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 365134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 366134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 367134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 368134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 369d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 370d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 371d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 3728aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 373bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 374bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 3753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { 3763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 3773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface result = EGL_NO_SURFACE; 3783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface old_surface = EGL_NO_SURFACE; 3793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian sp<SurfaceTextureClient> stc; 3803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (display != NULL) { 3823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian stc = new SurfaceTextureClient(display); 3833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian result = eglCreateWindowSurface(hw.getEGLDisplay(), 3843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL); 3853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(result == EGL_NO_SURFACE, 3863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian "eglCreateWindowSurface failed (ISurfaceTexture=%p)", 3873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian display.get()); 3883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 3893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 3913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 3923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian old_surface = mExternalDisplaySurface; 3933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplayNativeWindow = stc; 3943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface = result; 3953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGD("mExternalDisplaySurface = %p", result); 3963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 3973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (old_surface != EGL_NO_SURFACE) { 3993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // Note: EGL allows to destroy an object while its current 4003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // it will fail to become current next time though. 4013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglDestroySurface(hw.getEGLDisplay(), old_surface); 4023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 4033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 4043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const { 4063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 4073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian return mExternalDisplaySurface; 4083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 4093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 42399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 42699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 42799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 42899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 42999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 43099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 43199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 43299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 43399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 43499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 43599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 43699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 43799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 43899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 43999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 44099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 44599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 44699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) 44999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 4501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 45199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 45269a655caef30663403802281210363f643ceb946Mathias Agopian case MessageQueue::REFRESH: { 45369a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::INVALIDATE: { 45499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we're in a global transaction, don't do anything. 45599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 45699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 45799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(transactionFlags)) { 45899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleTransaction(transactionFlags); 45999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // post surfaces (if needed) 46299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handlePageFlip(); 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46469a655caef30663403802281210363f643ceb946Mathias Agopian// signalRefresh(); 46569a655caef30663403802281210363f643ceb946Mathias Agopian// 46669a655caef30663403802281210363f643ceb946Mathias Agopian// } break; 46769a655caef30663403802281210363f643ceb946Mathias Agopian// 46869a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::REFRESH: { 4693a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 470c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian handleRefresh(); 471a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 472303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 473303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 47469a655caef30663403802281210363f643ceb946Mathias Agopian// if (mDirtyRegion.isEmpty()) { 47569a655caef30663403802281210363f643ceb946Mathias Agopian// return; 47669a655caef30663403802281210363f643ceb946Mathias Agopian// } 47769a655caef30663403802281210363f643ceb946Mathias Agopian 478b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 479b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // build the h/w work list 480b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleWorkList(); 481b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian } 482303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 483b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_LIKELY(hw.canDraw())) { 484b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // repaint the framebuffer (if needed) 485b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian handleRepaint(); 486b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // inform the h/w that we're done compositing 487b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian hw.compositionComplete(); 488b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian postFramebuffer(); 489c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian } else { 490b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // pretend we did the post 491c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian hw.compositionComplete(); 49299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 493b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // render to the external display if we have one 4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface externalDisplaySurface = getExternalDisplaySurface(); 4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (externalDisplaySurface != EGL_NO_SURFACE) { 4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface cur = eglGetCurrentSurface(EGL_DRAW); 4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(), 4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian externalDisplaySurface, externalDisplaySurface, 5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglGetCurrentContext()); 5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> external failed"); 5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (success) { 5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // redraw the screen entirely... 5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glDisable(GL_TEXTURE_2D); 5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glClearColor(0,0,0,1); 5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glMatrixMode(GL_MODELVIEW); 5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glLoadIdentity(); 5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const size_t count = layers.size(); 5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const sp<LayerBase>& layer(layers[i]); 5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian layer->drawForSreenShot(); 5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface); 5203094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "external display eglSwapBuffers failed"); 5213094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5223094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian hw.compositionComplete(); 5233094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5243094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian success = eglMakeCurrent(eglGetCurrentDisplay(), 5263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian cur, cur, eglGetCurrentContext()); 5273094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5283094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> internal failed"); 5293094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5303094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } break; 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 537841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 538b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 539b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 540b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 541b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 542b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 543a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 544a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 545a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 546a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 547e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 548e8696a40e09b24b634214684d18526187b316a2fJamie Gennis size_t numLayers = mVisibleLayersSortedByZ.size(); 549ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 550ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 551ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 552ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 553ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 554ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur); 555ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 556ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 557ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 558ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL); 559ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 560e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 561e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 562a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 563a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 564a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 569841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 570841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 571ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 572ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 573ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 574ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 575ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 576ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 577ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 578ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 579ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 580ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 581ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 582ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 583ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 584ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 585ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 586ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 587ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 588ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 591ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5923d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 62521230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 6332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 6342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 6410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 6460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 6470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 64848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 6500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 6513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 6523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 6540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 6550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 6565d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 6570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 6580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 6661bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 668841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 669841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 683076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 698ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 705ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 71099ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 711a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 712970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 721ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 722ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 723ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 724ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 725ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 726ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 727ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 731ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 732ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 748a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 749ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 750ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 751ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 752ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 753ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 754ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 755ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 756ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 757ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 758ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 759a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 760ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 761ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 762ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 763ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 764ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 771ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 7738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 778970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 784970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 785970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 786970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 787970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7952f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall if (!mLayersPendingRemoval.isEmpty()) { 7962f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall // Notify removed layers now that they can't be drawn from 7972f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 7982f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval[i]->onRemoved(); 7992f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 8002f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.clear(); 8012f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 8022f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 80428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending = false; 805cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 8101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 81199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const DisplayHardware& hw = graphicPlane(0).displayHardware(); 81299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const Region screenRegion(hw.bounds()); 81399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 8141bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 81599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const bool visibleRegions = lockPageFlip(currentLayers); 816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 81799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (visibleRegions || mVisibleRegionsDirty) { 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 8204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 8214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 8224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 8234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 8241bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 8254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 8264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 8274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8284da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 8294da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 8304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 8314da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 834ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 8380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 8390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 843ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 844ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 845ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 846ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 847ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 852076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 854b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 865076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 867b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 87499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 87599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 87699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 87799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 87899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 87999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 88099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 88199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 88299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 88399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 88499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 88599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 88699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 88799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 88899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 893a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 894a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 8973e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 8983e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 8993e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 9003e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 9013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian currentLayers[i]->setGeometry(*cur); 90253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 9033e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 90473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 906a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 907a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 908b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 911841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 912841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 913b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 9140656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 91699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 920b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 921b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 922b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 923b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 926a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 92729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 92829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 92929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 930a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 93295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 93329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 934df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 93595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 93629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 9370656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 93929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 9410656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 945a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian setupHardwareComposer(); 946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9489c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 9499c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 953a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer() 954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 955f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 956f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 9573e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 9583e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 9593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 9603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 9619c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 963a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 96545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 966a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 967e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 96845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 96945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 970a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 97145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 97224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 97324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 97424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 975a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 97645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 97745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 97845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 97945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 9803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 981f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 9823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 983f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 984f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 985e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 986f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 987f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 988f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 989f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 990cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 991cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 9923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 9933e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 994cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 995cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 9963e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 997a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 99845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 999b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 1000b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1001b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1002b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1003b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1004b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1005b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1006b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1007b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1008b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 1009b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 1010b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 1011b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 1012b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1013a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 10144b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1015a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 1016a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 1017a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 10184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1019a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1020a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 10213e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1022a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 1023a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 1024a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 10253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur->getCompositionType() == HWC_OVERLAY) { 10263e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1027a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 1028b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 1029b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 1030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian layer->clearWithOpenGL(clip); 1031a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1032a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1033a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1034a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 1035a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian layer->draw(clip); 10364b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10374b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10384b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 10440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 104553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10460656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 104753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 104853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1050a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 10510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 10540a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10550a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1056c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1057c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 106820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 106920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 107020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 107120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 107353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 107453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 107553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 107653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10820656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10850a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1094f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1095b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1096f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1097b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1098f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1099f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1100f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1101f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1102f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1103f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1104f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1105f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1106f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1107f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1108f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1109f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1110f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1111f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1112f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1113f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1114f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1127f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 113196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 113296f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 113496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11354f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11364f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11374f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 113896f0819f81293076e652792794a961543e6750d7Mathias Agopian 113996f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 114096f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 114196f0819f81293076e652792794a961543e6750d7Mathias Agopian 11424f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 114396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 114496f0819f81293076e652792794a961543e6750d7Mathias Agopian 114596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 114696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 114796f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 114896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 114996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 115096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 115196f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1154076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1156b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11580d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1159b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1162076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 117076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 117176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 117376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 117476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 117576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11768c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11772f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 11780b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 118196f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 118296f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 118696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 118896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 118996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 119096f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1193dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1194dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1195dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1196dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1197dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1203bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 120799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1213b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 121428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1215698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1216cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 121728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1218b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1219b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1220b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 122128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1222b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 122332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1224b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1225b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1226b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1227b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1228698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1229698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1230698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1231698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 123228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1233698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1234386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 123528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1236386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 123728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1239386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1240386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1241386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1242386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1243386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1244386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1245386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1246386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1247386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1248386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 124932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1250386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1251386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1252386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1253cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12570ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 12580ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 12590ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 12600ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1264076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1265a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 12666e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12676e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1268e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12696e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1273ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1274b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1277a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1278a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12811293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12821293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 128496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1286118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1287118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1288118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 129296f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1293285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 129496f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 12978b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 129896f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1299a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1302a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 13041c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 130696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1313f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 131496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 13151c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1324a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1325a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1326a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 13278f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1328a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1332a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1333a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1334a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1335a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1336a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 133796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1338f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 133999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1340e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1341076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1347f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 134896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 135096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1351118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1352118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1353118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1354118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1355118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1356118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1357118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1358118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 136296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13680aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 137348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 137596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1376b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 137748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 137848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 137948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 138048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 138148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1386ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1388759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1389ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1390ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1391ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1392ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1393ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1394ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1395ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1396ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1397ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1398ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1399e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1400ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1401f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1402e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1408698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 140996f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1410698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1413698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1414698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1419698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1431698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1432698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1435698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1437698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1438698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1439698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1440698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1441698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1442698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1443698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1444698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1445698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1446698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1447698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1448698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1449698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1450698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1451f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1452f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1453f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1454f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1456698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1459b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1460b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1461b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 14628e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 1463b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 146522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 146922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 14708acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 14748e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 1475b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1476b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 147722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 14838e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1493b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1494b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14978e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1498b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1499b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1500b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1501b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1502b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1503b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1504b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1505b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1506b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1507b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1508b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1509b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1510b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1511b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1512b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15151d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 151899b49840d309727678b77403d6cc9f920111623fMathias Agopian 151999b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 154182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 154282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 154325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 154525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 154625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 154725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 154825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 154935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 155025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 155125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 155225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 155325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 155482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 155635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 155825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 155925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 156335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 156782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 156882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 156982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 157048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 157348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 157848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 157925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 158025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 158125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 158225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 158325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 158425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 158525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 158625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 158725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 158825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 158925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 159025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 159382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 159482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 159582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 159682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 159782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 159882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 159948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 160082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 160182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 160282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 160382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 160482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 160582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 160682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 160782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 160882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 160982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 161082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 161182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 161282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1613ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 161425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 161525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 161625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 161725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 161825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 161925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 162025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 162125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 162225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 162325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 162425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 162525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 162625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 162725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 162825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 162925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 163025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 163125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 163225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 163482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 163582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 163882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1642bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 164682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 165082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 165382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1654bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1658ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 166182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 166382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 16661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 166982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 16701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1680d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 168182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 168282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian eglQueryString(graphicPlane(0).getEGLDisplay(), 168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 168573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1698c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1701b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1702b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1705c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1708b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1709b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 172382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 172482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1750698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 175359119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 17558e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 17568e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1761a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 176299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 176399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1764e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1765375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1766375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 17691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 17711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 17721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 17731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 177699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 177799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1778e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 17791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 178999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1790375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1791375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1792375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1793e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1794375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 179901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 180035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 180653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 180953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1810cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1811cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1812cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1813cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1814cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 18164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 18174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 18184d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 18194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 182053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 182153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 182253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 182353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 182453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 182553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1826a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1827a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1828a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1829a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1830a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1831a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 183301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1836b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 183712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 185053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 185153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18520dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 18530dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 185499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 185553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 185653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 18570dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 18580dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18590dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 18600dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18610dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 18620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 18630dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 18650dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 18660dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 18670dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18680dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1871118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1872118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1873118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1874118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1875118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1876118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1877118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 188059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 188122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 188222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 188359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 188559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 189559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 189659119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 189959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 1900a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1901a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 190459119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1905015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 190659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 190759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 191059119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 191259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 191359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 191459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1919c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1920c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1923a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1924a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 193159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1932118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1933118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 193759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 194359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1946ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 1947ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 1948ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 1949ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 1950ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 1951ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 1952ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 1953ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 1954ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 1955ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 1956ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 1957ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1958ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1959ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1960ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 1961ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 1962ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1963ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 1964ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 1965ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 1966ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1967ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 1968ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 1969ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 1970ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1971ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1972ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1973ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 1974ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1981a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 198259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1985118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 198959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1991a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1996b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1997b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2002ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 2003ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 2004ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2005ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 2006ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 2007ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 2008ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 2009ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 2010ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2011ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2012ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2013ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 2014ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 2015ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2016ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 2017ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2042ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2043ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2044ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2045ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 205459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2060ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2061ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2062ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2063ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2067ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2068ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2070ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2071ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2072ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2073ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2074ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2075ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2081a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2082a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2083a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2084a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2085a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2086a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 210259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 211959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2133ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2134ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2135ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2136ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2146a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2147c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2178b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2179b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 220259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2234ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2235a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2236a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2248ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2249ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2250ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2251ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2258a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 226759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2268ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 229259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 229359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 229659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2297a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2298c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 229959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 230722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 230822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23147ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 23157ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 23167ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 23177ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 23187ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 23197ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2320abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2321abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2322abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2323abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2324abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2325abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2326abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2328abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2329015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 233059119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 233259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 233359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 233459119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 233559119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2336abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 233759119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 233859119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2339abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 234159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 234259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 234359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 234459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 234559119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 234659119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2347abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 234859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 234959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 235059119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 235159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2352abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 235359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 235459119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 235559119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2360abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 236159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 236259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 236359119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 236459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2367abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2374abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2375abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2376abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2377a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2378a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2379a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 238099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2381a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2382015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2389abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2392abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2393abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2400abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2405abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2414bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2415bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2417fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2418fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 242074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 242299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 243174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 243874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24409d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 24411c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2442c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 244674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2451fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 245274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 245374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 245474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 245774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2458c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 245974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 246074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 246174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 246274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 246374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2466ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2472f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 24739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 24749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2477b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2478b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2479b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2480b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2481b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian layer->drawForSreenShot(); 2482b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2483bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 248974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 249274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 249374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 249574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 249674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2498fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 249974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 250274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 250374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 250474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 250574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 250674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 250774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 250874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 250974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 251074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 251174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 251274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 251374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 251474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 251574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 251674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 251774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 251874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 251974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 252074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 252174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 252274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2523e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2524e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2525e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 25269d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2527c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 252874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 252974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 253074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 253174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 25331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 253474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2535bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2536bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 253999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 25401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 25411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 25431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 25441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 25511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 255374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2554bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2555bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 25581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2560bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2561bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2563bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2564bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2565bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 25661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 25691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 25701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 25721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 25731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 25751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 25761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 257874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2579bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2586bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2598b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2599b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2601b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2602b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 26037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2604b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 260596f0819f81293076e652792794a961543e6750d7Mathias Agopian 26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 26079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 26099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2611d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 26129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 26139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2614d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2615a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2616d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2617d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2618d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2619e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2620a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 26229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 26239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 26249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 26259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 26269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26279a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 26289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 26432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 26472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 26482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 26492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 26512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 26522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 26532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 26552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 26562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 26572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 26582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 26592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 26602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 26612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 26622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 26632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 26652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 26662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 26672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 26712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 26722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 26732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 26742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 26752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 26762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 26772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 26782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 26792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 26802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 26812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2687eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2688eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2691eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2692eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2694eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2697eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2700eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2705eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 27132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 27152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 27162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 27172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 27182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 27192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 27202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2721eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2722eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2723eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2724eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2725eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2727eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 27280d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 27292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273759119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 273859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 273959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 274059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2745076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2747076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2752