SurfaceFlinger.cpp revision a6b32db164e7834e211261046f3229bf50bc0098
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 62a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 63a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 651db13d79518f600d65a4fc006fe42900b890966eGlenn Kasten#include <private/android_filesystem_config.h> 6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/SharedBufferStack.h> 67ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian#include <gui/BitTube.h> 683094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian#include <gui/SurfaceTextureClient.h> 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 70bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 71bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 8099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 8199b49840d309727678b77403d6cc9f920111623fMathias Agopian 8299b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 8399b49840d309727678b77403d6cc9f920111623fMathias Agopian 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 91a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 92abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 96a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 1013330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 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); 145a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 146a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 147a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 15399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian setTransactionState(state, eOrientationDefault, 0); 15799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 159a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 16099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 16199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1627303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1647303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1677e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 17096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 17196f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 17296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 17396f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 188a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1893330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 1931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 1941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 1951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian window->linkToDeath(this); 1961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 1971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 199a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 200a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 201a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 204a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat( 205a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 206a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 207a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian PixelFormat format, 208a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 211a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 212a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian for (int i=0 ; i<n ; i++) { 216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint nativeVisualId = 0; 217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); 218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (nativeVisualId>0 && format == nativeVisualId) { 219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian *outConfig = configs[i]; 220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 228a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 231a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint attribs[] = { 235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_RECORDABLE_ANDROID, EGL_TRUE, 237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE 238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (err) { 241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // maybe we failed because of EGL_RECORDABLE_ANDROID 242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); 243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian attribs[2] = EGL_NONE; 244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); 247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { 248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 253a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) { 270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext); 271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!result) { 272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Couldn't create a working GLES context. check logs. exiting..."); 273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 2858b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint w, h; 287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_WIDTH, &w); 288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_HEIGHT, &h); 2898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 2927303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 3089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 3169575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 3179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 3189575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 3199575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 3209575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 3219575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3229575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3239575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3249575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 331ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 332ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopiansurface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const { 356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mServerCblk; 357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create the shared control-block 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize EGL 374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglInitialize(display, NULL, NULL); 376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Initialize the main display 378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create native window to main display 379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian sp<FramebufferSurface> anw = FramebufferSurface::create(); 380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ANativeWindow* const window = anw.get(); 381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!window) { 382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Display subsystem failed to initialize. check logs. exiting..."); 383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian int format; 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian window->query(window, NATIVE_WINDOW_FORMAT, &format); 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig = selectEGLConfig(display, format); 390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLContext = createGLContext(display, mEGLConfig); 391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize our main display hardware 393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig); 394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mDisplayHardwares[0] = hw; 395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLSurface surface = hw->getEGLSurface(); 398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian initializeGL(display, surface); 399d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 400d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 401d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 4028aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 405d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 406d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 407a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 408a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 4098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 413a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 414a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 415a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 416a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 417a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 418a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 419a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 420a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 422a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 423a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 424a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 425a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 426a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 427a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 429d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 430582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 431582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 432134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 433582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 434134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 435134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 436134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 437134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 438134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 439134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 440134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 441582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 442582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 443582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 444582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 445582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 446134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 447134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 448134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 449134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 450582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 451582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 458134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 459134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 463582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 464582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 467134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 468134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 471d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 472d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 473d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 4748aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 475bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 476bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 4773094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { 4781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 4793094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface result = EGL_NO_SURFACE; 4803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface old_surface = EGL_NO_SURFACE; 4813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian sp<SurfaceTextureClient> stc; 4823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (display != NULL) { 4843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian stc = new SurfaceTextureClient(display); 4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian result = eglCreateWindowSurface(hw.getEGLDisplay(), 486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig, (EGLNativeWindowType)stc.get(), NULL); 4873094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(result == EGL_NO_SURFACE, 4883094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian "eglCreateWindowSurface failed (ISurfaceTexture=%p)", 4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian display.get()); 4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian old_surface = mExternalDisplaySurface; 4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplayNativeWindow = stc; 4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface = result; 4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGD("mExternalDisplaySurface = %p", result); 4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (old_surface != EGL_NO_SURFACE) { 5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // Note: EGL allows to destroy an object while its current 5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // it will fail to become current next time though. 5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglDestroySurface(hw.getEGLDisplay(), old_surface); 5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const { 5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian return mExternalDisplaySurface; 5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 51399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 51499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 51599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 51699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 51799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 51999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 52099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 52699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 5501c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 5524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 5534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 5544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 5554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 5564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 5584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 5594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 5644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 5654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 5664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 5684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransaction(transactionFlags); 5694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 5714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 5754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handlePageFlip(); 5774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 5784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 5803a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRefresh(); 583a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 5843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (mVisibleRegionsDirty) { 5853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region opaqueRegion; 5863b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region dirtyRegion; 5873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 5883b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion); 5893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mDirtyRegion.orSelf(dirtyRegion); 5903b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 5913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian /* 5923b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian * rebuild the visible layer list per screen 5933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian */ 5943b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 5953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: iterate through all displays 5963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); 5973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 5983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 5993b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const size_t count = currentLayers.size(); 6003b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!currentLayers[i]->visibleRegion.isEmpty()) { 6023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: also check that this layer is associated to this display 6033b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layersSortedByZ.add(currentLayers[i]); 6043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6053b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6063b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.setVisibleLayersSortedByZ(layersSortedByZ); 6073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6083b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // FIXME: mWormholeRegion needs to be calculated per screen 6103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here 6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mWormholeRegion = Region(hw.getBounds()).subtract( 6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.getTransform().transform(opaqueRegion) ); 6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty = false; 6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian invalidateHwcGeometry(); 6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen, we should check all of them 6194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (mDirtyRegion.isEmpty()) { 6204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return; 6214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 622303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 6234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: iterate through all displays 6244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const DisplayHardware& hw(getDisplayHardware(0)); 62569a655caef30663403802281210363f643ceb946Mathias Agopian 6264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 6274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region into this screen's coordinate space 6284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& planeTransform(hw.getTransform()); 6294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion = planeTransform.transform(mDirtyRegion); 6304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 6314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.andSelf(hw.bounds()); 632303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 633b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 6344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // build the h/w work list 6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleWorkList(hw); 6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6383094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_LIKELY(hw.canDraw())) { 6404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // repaint the framebuffer (if needed) 6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRepaint(hw); 6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // inform the h/w that we're done compositing 6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian postFramebuffer(); 6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // pretend we did the post 6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6493094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // render to the external display if we have one 6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface externalDisplaySurface = getExternalDisplaySurface(); 6524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (externalDisplaySurface != EGL_NO_SURFACE) { 6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface cur = eglGetCurrentSurface(EGL_DRAW); 6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(), 6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian externalDisplaySurface, externalDisplaySurface, 6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian eglGetCurrentContext()); 6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> external failed"); 6594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (success) { 6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // redraw the screen entirely... 6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_2D); 6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClearColor(0,0,0,1); 6654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glMatrixMode(GL_MODELVIEW); 6674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glLoadIdentity(); 6683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); 6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = layers.size(); 6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; ++i) { 6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian layer->drawForSreenShot(hw); 6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6753094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface); 6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "external display eglSwapBuffers failed"); 6783094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglMakeCurrent(eglGetCurrentDisplay(), 6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian cur, cur, eglGetCurrentContext()); 6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> internal failed"); 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 692841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 693b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 694b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 695b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 696b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 697b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 6981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 699c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall HWComposer& hwc(hw.getHwComposer()); 7003b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 7013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian size_t numLayers = layers.size(); 702a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 703a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 704c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 705c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (hwc.initCheck() == NO_ERROR) { 706c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 707c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall const HWComposer::LayerListIterator end = hwc.end(); 708c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 709c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (cur->getCompositionType() == HWC_OVERLAY) { 7103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->setAcquireFence(*cur); 711c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } else { 712c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall cur->setAcquireFenceFd(-1); 713c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 714c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 715c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 716c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 717a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 718e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 719ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 720ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 721ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 722ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 7233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(&*cur); 724ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 725ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 726ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 7273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(NULL); 728ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 729e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 730e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 731a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 732a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 733a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 738841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 739841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 7404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 742ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 743ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 744ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 745ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 746ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 747ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 748ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 749ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 750ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 751ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 752ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 753ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 7544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransactionLocked(transactionFlags); 755ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 756ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 757ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 758ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 759ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 7604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 7614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 7623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 7653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 7664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7673d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const int dpy = 0; // TODO: should be a parameter 7981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 8001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian hw.setOrientation(orientation); 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 8051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->w = hw.getUserWidth(); 8061b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian dcblk->h = hw.getUserHeight(); 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8081b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware? 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8130aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 8140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8180aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 8190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 8200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 82148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 8230aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 8243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 8253d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 8270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 8280aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 8294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could traverse the tree from front to back and compute the actual visible region 8304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could cache the transformed region 8314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Layer::State front(layer->drawingState()); 8324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region visibleReg = front.transform.transform( 8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region(Rect(front.active.w, front.active.h))); 8344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf(visibleReg); 8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 8360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 8424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 8464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 8474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 8484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 8494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 8524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransationPending = false; 8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 8601bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 862841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8683b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian dirtyRegion.clear(); 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 872076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 875970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 877ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 878ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 879ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 881ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 882ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 883ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 884ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 885ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 886ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 887ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 89899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 899a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 9004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 9054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region transparentRegionScreen; 9064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 9074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 9084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 9094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 9104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = tr.transform(s.transparentRegion); 9114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 9144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen.clear(); 9154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = s.transparentRegion; 9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian visibleRegion.subtractSelf(transparentRegionScreen); 920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 922ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 924ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 925ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 926ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 927ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 928ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 933ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 9464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 949a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 950ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 951ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 952ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 953ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 955ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 956ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 959ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 960a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 9624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 9634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 9748b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip() 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 9864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 98799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 9881bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 9914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 9924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 9934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 9944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 9954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) ); 9964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9974da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 9983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 9990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 10004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1003ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1004ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1005ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1006ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1007ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 100899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 100999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 101099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 101199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 101299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 101399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 101499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 101599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 101699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 101799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 101899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 101999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 102099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 102199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 102299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 102499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 10251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw) 1026a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 1027a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 10281b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 1029a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 10303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); 1031a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 1032a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 10333e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 10343e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 10353e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 10363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian currentLayers[i]->setGeometry(hw, *cur); 103853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 10393e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 104073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 1041a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1042a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1043a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 1044b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 10451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw) 1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1047841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1048841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1049b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 10500656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 10531b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian debugFlashRegions(hw); 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1056b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 1057b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 1058b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 1061a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 106229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 106329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 106429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 1065a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 106795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 106829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1069df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 107095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 107129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 10720656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 107429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 10760656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian setupHardwareComposer(hw); 10811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, mDirtyRegion); 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10839c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 10849c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1090f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 10913e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 10923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 10933e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 10949c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1096a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 10973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 109845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 1099a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1100e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 110145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 110245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 1103a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 110445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 110524925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 110624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 110724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 1108a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 110945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 111045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 111145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 111245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 11133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1114f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11153e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 1116f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 1117f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 1118e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 1119f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 1120f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 11211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) 1122f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 1123cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian HWComposer& hwc(hw.getHwComposer()); 11243e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 11253e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 1126cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 1127cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 11283e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 1129a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 113045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 1131b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 1132b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1133b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1134b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1135b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1136b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1137b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1138b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1139b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1140b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 1141b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 1142b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 1143b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 1144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1145a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 11464b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1147a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 1148a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 1149a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 11504b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 11513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 1152a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 11534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& tr = hw.getTransform(); 1154a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall for (size_t i=0 ; i<count ; ++i) { 1155a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 1157a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 1158a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end && cur->getCompositionType() == HWC_OVERLAY) { 11593e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1160a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 1161b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 1162b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 11631b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->clearWithOpenGL(hw, clip); 1164a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1165a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 11681b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->draw(hw, clip); 11694b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1170a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end) { 1171a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall ++cur; 1172a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 11734b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 11744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw) 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11790a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 118053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 11810656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 118253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 118353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 11840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1185a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 11860a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 11870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 11881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, repaint); 11890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 11900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1191c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1192c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11950926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 11960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 11970926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 11980a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 11990926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 12000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 12010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 120420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 120520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 120620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 120853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 120953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 121053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 121153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12160a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 12170656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 12200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1229f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1230b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1231f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1232b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1233f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1234f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1235f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1236f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1237f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1238f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1239f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1240f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1241f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1243f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1245f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1260076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1262f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 12631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 12641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 12651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 126696f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 126796f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 12681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 126996f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 12704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 12714f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 12724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 127396f0819f81293076e652792794a961543e6750d7Mathias Agopian 127496f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 127596f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 127696f0819f81293076e652792794a961543e6750d7Mathias Agopian 12774f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 127896f0819f81293076e652792794a961543e6750d7Mathias Agopian} 127996f0819f81293076e652792794a961543e6750d7Mathias Agopian 128096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 128196f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 128296f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 128396f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 128496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 128596f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 128696f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 12930d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1297076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13003d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 13049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 130576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 130676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 13079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 130876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 131076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 13118c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 13122f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 13130b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 13143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 13153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 131696f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 131796f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 13189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 13199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 132196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 132396f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 132496f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 132596f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1328dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1329dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1330dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1331dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1332dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 134299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1348b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 134928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1350698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1351cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 135228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1353b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1354b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 135628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1357b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 135832397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1359b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1361b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1363698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 136728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1369386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 137028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1371386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 137228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 138432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1385386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1388cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13920ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 13930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13940ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 13950ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1399076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 14016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1403e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 14046e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 14056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 14078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1408ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1412a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1413a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 14161293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 14171293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 141996f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1421118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1422118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1423118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1426076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 142796f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1428285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 142996f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 14328b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 143396f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1434a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1437a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 14391c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1440b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 144196f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1448f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 144996f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 14501c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1459a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1461a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 14628f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1463a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1467a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1469a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1470a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1471a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 147296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1473f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 147499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1475e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1481b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1482f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 148396f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 148596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1486118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1491118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1492118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1493118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 14989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 14999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 15009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 15019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 15028b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 15030aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 15040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 15050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 15069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 150848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 15090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 151096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1511b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 151248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 151448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 151548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 151648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 15179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 15189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 15199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 15209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1523759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1534e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1536f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1537e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1538ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1543698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 154496f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1584698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1585698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1586f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1587f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1588f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1589f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1591698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1594b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 15978e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 15981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1599b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 160022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1602b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 160422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 16058acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1608b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 16098e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 16101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1611b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 161222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 16188e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16328e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1633b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16501d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 165399b49840d309727678b77403d6cc9f920111623fMathias Agopian 165499b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 16619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 16708b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 16719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 16739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 167825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 168435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 168525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 168982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 169135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 169325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 169425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 169525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 169835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 169925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 170282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 170548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 170848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 171348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 171425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 173448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1748ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 174925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 176882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1777bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1789bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1793ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 18011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 18051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 18091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 181282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1816d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 18181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian eglQueryString(hw.getEGLDisplay(), 181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 182173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1833c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1836b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1840c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1843b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1844b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ()); 187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1885698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 188859119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 18908e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 18918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1896a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 189799b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 189899b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1899e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1900375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1901375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 191199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 191299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1913e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 19141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 19151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 19161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1923b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 192499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1925375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1926375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1927375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1928e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1929375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 193401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 193535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 194053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 194153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 194453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1945cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1946cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1947cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19514d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 19524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 19534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 195553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 195653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 195753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1961a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1962a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1963a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 196801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1971b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 197212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 19761b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 198553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 19861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display 19870dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 198999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 199053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 199153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 19920dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 200459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2006118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 2007118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2008118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 201622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 201722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 20221b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2035a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2036a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2040015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 204159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2054c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2058a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 20603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 20641b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2067118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 2068118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 207259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 207859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 208059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2081ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 2116a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 211759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 2120118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 212459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 2126a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 21279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2131b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2132b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2137ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 21539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2177ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2178ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2179ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 218959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2195ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2196ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2197ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2202ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2203ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2205ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2206ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2207ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 22119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2216a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2217a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2218a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 22229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2230ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2232ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 223759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 225459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2268ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2281a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2282c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 22951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2313b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2314b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 233759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2368ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2369ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2370a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2371a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 23729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2383ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2384ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2385ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 23879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2393a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 240259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2403ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2404ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2405ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 24069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 240759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 24089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 242759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 243159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2432a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2433c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 243459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 24379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2440abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 244222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 244322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 24441b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 24459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 24469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 24479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 24497ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 24507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 24517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 24547ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2455abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2464015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 246559119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 246759119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 246859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2471abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2474abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2475abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 247659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2482abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248559119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2487abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 248859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 24919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 24939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2495abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 249659119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 249759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 249859119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2502abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 25039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25041b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 25059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 25079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2509abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2510abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2511abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2512a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2513a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2514a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 251599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2516a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2517015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 25189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2524abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2527abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2528abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 25299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2535abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2540abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 25419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 254674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 254774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2549bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2550bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 255174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2552fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2553fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 255574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 25573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { 255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25593b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 256274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 25633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 25661b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 256774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 256974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25703b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (hw.getSecureLayerVisible()) { 25723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 257674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 257874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25839d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 25841c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2585c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 258674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 258874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2594fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 259574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2601c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2609ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 261074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2615f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 26169575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 26179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 261874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 261974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2620b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2621b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2622b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 26241b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 2625b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2626bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 262774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2641fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2666e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2667e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2668e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 26699d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2670c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 267174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 267274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 267374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 26761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 267774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2678bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2679bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 26801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 268299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 269574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2697bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 26991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 27001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 27011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 270274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2703bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2704bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2706bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2708bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 27091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 271674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2717bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2723bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2733b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2735b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 27407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 274296f0819f81293076e652792794a961543e6750d7Mathias Agopian 27439a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 27449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27459a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 27469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2748d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 27499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 27509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2751d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2752a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2753d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2754d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2755d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2756e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 27599a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 27609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 27639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2767