SurfaceFlinger.cpp revision 1b03149f3533db04e72e088d3fdd09d0087ca594
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" 531b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.h" 54db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 55d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 561f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 59118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 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 Projectvoid SurfaceFlinger::bootFinished() 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 185a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1863330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 1891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 196a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 197a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 198a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 2151b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // TODO: initialize all displays 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 2171b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian mDisplayHardwares[0] = hw; 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2207303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2217303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 223e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 226e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2278b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 2341b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2441b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->w = w; // XXX: plane.getWidth(); 2451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->h = h; // XXX: plane.getHeight(); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2558b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 2639575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 2719575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 2729575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 2739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 2749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 2759575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 2769575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 2799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 2809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 2819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 286ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 287ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 289d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 290d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 291d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 2928aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 298d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 299d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 300a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 301a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 3028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 306a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 307a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 308a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 309a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 310a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 311a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 313d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 314582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 315582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 316134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 317582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 318134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 319134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 320134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 321134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 322134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 323134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 324134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 325582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 326582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 327582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 328582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 329582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 330134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 331134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 332134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 333134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 334582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 335582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 336134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 337134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 338134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 339134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 340134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 341134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 342134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 343134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 344582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 345582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 346582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 347582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 348582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 349134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 350134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 351134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 352134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 353134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 354134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 355d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 356d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 357d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 3588aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 359bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 360bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 3613094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { 3621b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 3633094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface result = EGL_NO_SURFACE; 3643094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface old_surface = EGL_NO_SURFACE; 3653094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian sp<SurfaceTextureClient> stc; 3663094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3673094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (display != NULL) { 3683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian stc = new SurfaceTextureClient(display); 3693094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian result = eglCreateWindowSurface(hw.getEGLDisplay(), 3703094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL); 3713094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(result == EGL_NO_SURFACE, 3723094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian "eglCreateWindowSurface failed (ISurfaceTexture=%p)", 3733094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian display.get()); 3743094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 3753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 3773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 3783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian old_surface = mExternalDisplaySurface; 3793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplayNativeWindow = stc; 3803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface = result; 3813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGD("mExternalDisplaySurface = %p", result); 3823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 3833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (old_surface != EGL_NO_SURFACE) { 3853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // Note: EGL allows to destroy an object while its current 3863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // it will fail to become current next time though. 3873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglDestroySurface(hw.getEGLDisplay(), old_surface); 3883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 3893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 3903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 3913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const { 3923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 3933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian return mExternalDisplaySurface; 3943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 3953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 39799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 39899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 39999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 40099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 40199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 40299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 40399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 40499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 40599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 40699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 40799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 40899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 40999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 41099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 41199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 41299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 41399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 41499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 41599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 41699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 41799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 41899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 41999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 42099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 42199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 42299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 42399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 42499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 42599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 42699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 43199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 43299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) 43599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 4361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 43799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 43869a655caef30663403802281210363f643ceb946Mathias Agopian case MessageQueue::REFRESH: { 43969a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::INVALIDATE: { 44099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we're in a global transaction, don't do anything. 44199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 44299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 44399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (CC_UNLIKELY(transactionFlags)) { 44499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handleTransaction(transactionFlags); 44599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // post surfaces (if needed) 44899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian handlePageFlip(); 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45069a655caef30663403802281210363f643ceb946Mathias Agopian// signalRefresh(); 45169a655caef30663403802281210363f643ceb946Mathias Agopian// 45269a655caef30663403802281210363f643ceb946Mathias Agopian// } break; 45369a655caef30663403802281210363f643ceb946Mathias Agopian// 45469a655caef30663403802281210363f643ceb946Mathias Agopian// case MessageQueue::REFRESH: { 4553a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 456c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian handleRefresh(); 457a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 4581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // TODO: iterate through all displays 4591b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(0)); 460303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 46169a655caef30663403802281210363f643ceb946Mathias Agopian// if (mDirtyRegion.isEmpty()) { 46269a655caef30663403802281210363f643ceb946Mathias Agopian// return; 46369a655caef30663403802281210363f643ceb946Mathias Agopian// } 46469a655caef30663403802281210363f643ceb946Mathias Agopian 465b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 466b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // build the h/w work list 4671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian handleWorkList(hw); 468b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian } 469303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 470b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian if (CC_LIKELY(hw.canDraw())) { 471b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // repaint the framebuffer (if needed) 4721b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian handleRepaint(hw); 473b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // inform the h/w that we're done compositing 474b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian hw.compositionComplete(); 475b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian postFramebuffer(); 476c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian } else { 477b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // pretend we did the post 478c9ca7011501cb8730ce4e6e527cb402adb7a0178Mathias Agopian hw.compositionComplete(); 47999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 480b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 4813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // render to the external display if we have one 4823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface externalDisplaySurface = getExternalDisplaySurface(); 4833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (externalDisplaySurface != EGL_NO_SURFACE) { 4843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface cur = eglGetCurrentSurface(EGL_DRAW); 4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(), 4863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian externalDisplaySurface, externalDisplaySurface, 4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglGetCurrentContext()); 4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> external failed"); 4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (success) { 4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // redraw the screen entirely... 4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glDisable(GL_TEXTURE_2D); 4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glClearColor(0,0,0,1); 4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glMatrixMode(GL_MODELVIEW); 4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian glLoadIdentity(); 4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const size_t count = layers.size(); 5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian const sp<LayerBase>& layer(layers[i]); 5031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface); 5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "external display eglSwapBuffers failed"); 5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian hw.compositionComplete(); 5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian success = eglMakeCurrent(eglGetCurrentDisplay(), 5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian cur, cur, eglGetCurrentContext()); 5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> internal failed"); 5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } break; 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 524841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 525b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 526b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 527b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 528b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 529b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 5301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 531a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 532a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 533a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 534e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 535e8696a40e09b24b634214684d18526187b316a2fJamie Gennis size_t numLayers = mVisibleLayersSortedByZ.size(); 5361b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 537ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 538ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 539ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 540ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 541ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur); 542ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 543ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 544ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 545ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL); 546ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 547e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 548e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 549a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 550a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 551a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 556841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 557841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 559ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 560ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 561ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 562ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 563ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 564ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 565ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 566ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 567ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 568ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 569ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 570ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian handleTransactionLocked(transactionFlags); 571ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 572ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 573ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 574ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 575ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 5763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 578ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 5793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 5803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const int dpy = 0; // TODO: should be a parameter 6111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 6131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian hw.setOrientation(orientation); 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 6181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->w = hw.getUserWidth(); 6191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->h = hw.getUserHeight(); 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware? 622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 6270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 6320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 6330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 63448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 6360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 6373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 6383d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 6400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 6410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 6425d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 6430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 6440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 6521bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 654841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 655841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 6561b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: we shouldn't rely on DisplayHardware here 6571b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const Transform& planeTransform(hw.getTransform()); 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 668076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 6691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->validateVisibility(planeTransform, hw); 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 672970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 676ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 679ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 693ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 69599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 696a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 697970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 699ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 700ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 701ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 703ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 720ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 721ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 733a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 737ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 738ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 739ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 740ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 741ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 742ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 743ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 744a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 745ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 746ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 747ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 748ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 749ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 756ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 7588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 763970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 769970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 770970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 771970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 772970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7802f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall if (!mLayersPendingRemoval.isEmpty()) { 7812f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall // Notify removed layers now that they can't be drawn from 7822f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 7832f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval[i]->onRemoved(); 7842f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7852f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.clear(); 7862f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall } 7872f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 78928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending = false; 790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7951c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 7961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here 79799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const Region screenRegion(hw.bounds()); 79899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 7991bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 80099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const bool visibleRegions = lockPageFlip(currentLayers); 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 80299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (visibleRegions || mVisibleRegionsDirty) { 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 8054da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 8064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 8074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 8084da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 8091bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const size_t count = currentLayers.size(); 8104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 8114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 8124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 8144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 8154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 8164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 819ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 8230dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 8240dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 828ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 829ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 830ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 831ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 832ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 837076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 839b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 8471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here 8481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const Transform& planeTransform(hw.getTransform()); 84999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 850076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 852b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 85799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 85899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 85999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 86099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 86199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 86599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 86699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 86799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 86899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 86999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 87099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 87199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 8741b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw) 875a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 876a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 8771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 881a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 8823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 8833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 8843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 8853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 8863e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian currentLayers[i]->setGeometry(*cur); 88753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 8883e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 88973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 893b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 8941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw) 895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 896841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 897841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 898b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 8990656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 90199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 9021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian debugFlashRegions(hw); 903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 905b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 906b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 907b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 910a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 91129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 91229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 91329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 914a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 91695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 91729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 918df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 91995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 92029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 9210656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 92329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 9250656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9291b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian setupHardwareComposer(hw); 9301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, mDirtyRegion); 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9329c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 9339c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) 938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 939f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 9403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 9413e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 9423e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 9439c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 945a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 9464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 94745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 948a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 949e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 95045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 95145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 952a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 95345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 95424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 95524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 95624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 957a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 95845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 95945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 96045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 96145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 9623e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 963f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 9643e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 965f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 966f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 967e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 968f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 969f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 9701b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) 971f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 972cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 9733e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 9743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 975cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 976cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 9773e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 978a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 97945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 980b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 981b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 982b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 983b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 984b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 985b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 986b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 987b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 988b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 989b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 990b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 991b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 992b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 993b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 994a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 9954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 996a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 997a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 998a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 9994b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1000a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1001a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 10023e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1003a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 1004a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 1005a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 10063e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur->getCompositionType() == HWC_OVERLAY) { 10073e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1008a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 1009b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 1010b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 10111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->clearWithOpenGL(hw, clip); 1012a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1013a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1014a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1015a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 10161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->draw(hw, clip); 10174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 10194b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10221b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw) 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 102553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 10260656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 102753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 102853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 10290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1030a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 10310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 10320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 10331b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, repaint); 10340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 10350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1036c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1037c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 10410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 10420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 10430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 10440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 10450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 10460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 104920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 105020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 105120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 105353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 105453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 105553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 105653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10610a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 10620656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 10650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1074f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1075b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1076f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1078f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1079f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1080f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1081f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1082f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1083f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1084f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1085f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1086f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1087f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1088f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1089f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1090f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1091f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1092f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1093f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1094f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1097076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1107f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 11081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 11091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 11101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 111196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 111296f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 11131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 111496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 11154f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 11164f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 11174f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 111896f0819f81293076e652792794a961543e6750d7Mathias Agopian 111996f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 112096f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 112196f0819f81293076e652792794a961543e6750d7Mathias Agopian 11224f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 112396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 112496f0819f81293076e652792794a961543e6750d7Mathias Agopian 112596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 112696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 112796f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 112896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 112996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 113096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 113196f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 11380d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 115076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 115176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 115376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 115476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 115576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11568c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11572f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 11580b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 116196f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 116296f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 116696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 116896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 116996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 117096f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1173dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1174dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1175dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1176dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1177dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1183bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 118799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1193b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 119428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1195698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1196cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 119728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1198b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1199b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1200b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 120128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1202b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 120332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1204b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1205b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1206b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1207b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1208698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1209698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1210698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1211698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 121228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1213698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1214386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 121528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1216386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 121728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1218698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1219386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1220386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1221386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1222386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1223386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1224386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1225386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1226386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1227386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1228386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 122932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1230386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1231386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1232386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1233cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12370ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 12380ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 12390ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 12400ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1244076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1245a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 12466e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12476e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1248e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12496e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12506e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12516e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12528b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1253ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1254b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1257a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1258a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12611293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12621293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 126496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1266118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1267118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1268118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1271076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 127296f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1273285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 127496f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 12778b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 127896f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1279a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1282a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 12841c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 128696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1293f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 129496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 12951c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1304a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1305a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1306a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 13078f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1308a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1312a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1313a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1314a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1315a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1316a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 131796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1318f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 131999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1320e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1321076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1327f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 132896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 133096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1331118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1332118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1333118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1334118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1335118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1336118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1337118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1338118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13478b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13519a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 135348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 135596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1356b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 135748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 135848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 135948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 136048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 136148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1366ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1368759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1369ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1370ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1371ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1372ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1373ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1374ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1375ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1376ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1377ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1378ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1379e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1380ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1381f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1382e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1383ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1384ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1385ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1388698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 138996f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1390698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1393698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1394698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1395698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1396698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1397698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1398698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1399698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1400698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1401698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1402698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1403698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1404698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1405698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1406698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1407698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1409698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1410698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1411698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1412698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1415698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1416698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1417698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1418698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1419698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1421698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1422698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1423698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1424698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1425698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1426698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1427698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1428698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1429698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1430698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1431f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1432f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1433f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1434f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1436698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1439b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1440b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1441b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 14428e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 14431b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1444b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 144522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1446b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1447b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1448b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 144922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 14508acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1453b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 14548e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 14551b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1456b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 145722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1458b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1459b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1460b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1461b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1462b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 14638e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1465b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1466b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1467b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1469b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1470b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1471b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1472b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1473b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1474b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14778e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1478b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1482b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1483b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1488b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1489b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1490b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1491b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1492b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14951d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 149899b49840d309727678b77403d6cc9f920111623fMathias Agopian 149999b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 15158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 152182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 152282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 152325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 152425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 152525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 152625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 152725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 152825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 152935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 153025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 153125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 153225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 153325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 153482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 153582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 153635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 153782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 153825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 153925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 154025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 154125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 154225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 154335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 154425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 154782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 154882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 154982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 155048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 155182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 155282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 155348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 155482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 155582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 155682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 155782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 155848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 155925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 156025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 156125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 156225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 156325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 156425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 156525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 156625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 156725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 156825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 156925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 157025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 157182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 157282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 157382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 157482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 157582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 157682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 157782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 157882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 157948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 158082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 158182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 158282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 158382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 158482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 158582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 158682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 158782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 158882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 158982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 159082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 159182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 159282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1593ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 159425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 159525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 159625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 159725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 159825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 159925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 160025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 160125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 160225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 160325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 160425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 160525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 160625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 160725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 160825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 160925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 161025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 161125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 161225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 161382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 161482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 161582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 161682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 161782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 161882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 161982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 162082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 162182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1622bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 162382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 162482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 162582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 162682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 162782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 162882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 162982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 163082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 163182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 163282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 163382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1634bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 163582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 163682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 163782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1638ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 163982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 164082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 164182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 164282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 164382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 164482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 164582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 16461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 164782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 164882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 164982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 16501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 165182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 165282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 16541b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 165582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 165682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 165782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 165882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 165982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 166082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1661d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 166282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 16631b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian eglQueryString(hw.getEGLDisplay(), 166482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 166582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 166673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 166782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 166882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 167182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 167282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 167382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 167482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 167582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1678c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1681b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1682b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 168382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 168482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1685c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 168682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 168782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1688b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1689b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 169482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 169682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 169782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 169882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 170182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 171682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 171782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 171882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 171982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 172082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 172182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 172282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1730698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 173359119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 17358e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 17368e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1741a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 174299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 174399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1744e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1745375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1746375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 17491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 17511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 17521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 17531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 17541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 17551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 175699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 175799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1758e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 17591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 17601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 17611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 17621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1768b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 176999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1770375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1771375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1772375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1773e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1774375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 177901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 178035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 178553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 178653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 178953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1791cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1792cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17964d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 17974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 17984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 17994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 180053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 180153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 180253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 180353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 180453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 180553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1806a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1807a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1808a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1809a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1810a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1811a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 181301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1816b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 181712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 18211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 183053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 18311b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display 18320dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 18330dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 183499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 183553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 183653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 18370dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 18380dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18390dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 18400dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18410dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 18420dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 18430dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 18440dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 18450dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 18460dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 18470dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 18480dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 184959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 185059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1851118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1852118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1853118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1854118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 1855118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1856118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1857118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 186059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 186122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 186222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 186359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 186459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 186559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 186659119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 18671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 186859119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 186959119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 187159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 187359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 187459119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 187559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 187659119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 187759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 187859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 187959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 1880a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1881a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 188459119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1885015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 188759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 189059119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 189459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 1899c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1900c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1903a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 1904a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 19091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 191159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1912118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 1913118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1926ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 1927ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 1928ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 1929ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 1930ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 1931ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 1932ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 1933ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 1934ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 1935ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 1936ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 1937ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1938ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1939ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1940ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 1941ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 1942ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1943ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 1944ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 1945ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 1946ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1947ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 1948ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 1949ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 1950ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 1951ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 1952ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 1953ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 1954ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 19581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 1961a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 196259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 1965118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 196959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 1971a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1976b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1977b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1982ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 1983ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 1984ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1985ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 1986ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 1987ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 1988ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 1989ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 1990ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1991ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1992ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 1993ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 1994ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 1995ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1996ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 1997ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 20009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 20069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 20209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2022ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2023ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2024ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2025ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 20309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 20319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 20329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 20339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2040ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2041ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2042ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2043ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2047ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2048ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2050ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2051ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2052ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2053ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2054ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2055ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2061a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2062a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2063a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2064a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2065a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2066a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2075ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2076ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2077ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 208259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 209959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 210059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 21089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2113ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2114ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2115ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2116ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2127c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21401b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 21419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 21439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 21449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 21479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 21489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2158b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2159b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 218259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 22069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 22089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 22099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 22109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2213ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2214ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2215a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2216a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2228ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2229ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2230ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2238a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 224759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2248ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2249ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2250ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 225259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 227259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 227359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 227659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2277a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2278c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 227959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2285abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 228722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 228822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 22891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22947ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 22957ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 22967ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 22977ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 22987ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 22997ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2300abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2301abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2302abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2303abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2304abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2305abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2306abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2307abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2308abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2309015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 231059119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 231159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 231259119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 231359119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 231459119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 231559119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2316abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 231759119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 231859119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2319abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2320abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 232159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 232259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 232359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 232459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 232559119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 232659119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2327abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 232859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 232959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 233059119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 233159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2332abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 233359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 233459119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 233559119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2340abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 234159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 234259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 234359119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 234459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2347abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23491b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2354abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2355abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2356abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2357a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2358a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2359a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 236099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2361a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2362015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2369abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 23719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2372abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2373abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2380abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2385abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 23869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 239174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 239274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 239374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2394bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2395bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 239674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2397fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2398fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 239974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 240074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 240299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 240374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 240474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 240674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 240774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 240874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 24091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 241074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 241174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 241274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 241474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 241574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 241674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 241774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 241874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 241974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 24209d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 24211c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2422c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 242374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 242474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 242574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 242674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 242774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 242874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 242974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 243074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2431fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 243274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 243374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 243474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 243574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 243674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 243774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2438c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 243974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 244074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 244174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 244274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 244374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 244474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 244574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2446ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 244774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 244874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 244974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 245074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 245174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2452f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 24539575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 24549575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 245574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 245674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2457b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2458b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2459b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2460b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 24611b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 2462b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2463bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 246474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 246574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 246674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 246774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 246874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 246974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 247074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 247174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 247274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 247374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 247474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 247574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 247674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 247774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2478fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 247974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 248074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 248174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 248274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 248374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 248474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 248574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 248674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 248774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 248874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 248974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 249074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 249174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 249274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 249374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 249474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 249574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 249674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 249774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 249874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 249974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 250074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 250174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 250274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2503e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2504e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2505e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 25069d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2507c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 250874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 250974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 251074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 251174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 25131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 251474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2515bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2516bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 251999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 25201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 25231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 25241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 25261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 25271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 25281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 25291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 25301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 25311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 253274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 253374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2534bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2535bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 25361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 25371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 25381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 253974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2540bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2541bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 25421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2543bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2544bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2545bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 25521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 25531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 25551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2559bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 25601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 25621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 25641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2566bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 25671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 25681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 25691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 25701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 25721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 25731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 25741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 25751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2576b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2580b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2581b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2582b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 25837303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2584b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 258596f0819f81293076e652792794a961543e6750d7Mathias Agopian 25869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 25879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 25899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2591d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 25929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 25939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2594d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2595a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2596d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2597d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2598d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2599e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2600a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2601a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 26029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 26039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 26049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 26059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 26069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 26079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 26089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2610