SurfaceFlinger.cpp revision 6ee93c0d36dff1339eb2428be2d65441398e6e5f
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 } 11656ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall ++cur; 1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1167a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1168a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 11691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->draw(hw, clip); 11704b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1171a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end) { 1172a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall ++cur; 1173a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 11744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 11754b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw) 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 118153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 11820656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 118353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 118453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 11850a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1186a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 11870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 11880a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 11891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, repaint); 11900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 11910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1192c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1193c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 11970926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 11980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 11990a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 12000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 12010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 12020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 120520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 120620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 120720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 120953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 121053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 121153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 121253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12170a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 12180656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 12210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1230f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1231b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1232f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1233b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1234f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1235f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1236f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1237f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1238f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1239f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1240f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1241f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1242f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1243f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1244f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1245f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1246f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1247f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1248f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1249f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1250f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1253076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1261076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1263f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 12641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 12651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 12661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 126796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 126896f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 12691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 127096f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 12714f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 12724f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 12734f113740180b6512b43723c4728f262882dc9b45Mathias Agopian Mutex::Autolock _l(mStateLock); 127496f0819f81293076e652792794a961543e6750d7Mathias Agopian 127596f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 127696f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 127796f0819f81293076e652792794a961543e6750d7Mathias Agopian 12784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 127996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 128096f0819f81293076e652792794a961543e6750d7Mathias Agopian 128196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 128296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 128396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 128496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 128596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 128696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 128796f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 12940d1561275e80073807ac04728951782d943f8882Mathias Agopian mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1298076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 13059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 130676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 130776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 13089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 131076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 131176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 13128c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 13132f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 13140b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 13153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 13163d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 131796f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 131896f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 13199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 13209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 132296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 132496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 132596f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 132696f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1329dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1330dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1331dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1332dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1333dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 134399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1349b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennisvoid SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 135028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis int orientation, uint32_t flags) { 1351698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1352cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 135328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1354b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1355b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1356b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 135728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 135932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1361b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1363b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1364698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1366698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1367698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 136828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1370386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 137128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1372386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 137328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1374698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1375386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1377386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1378386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 138532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1389cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopiansp<ISurface> SurfaceFlinger::createSurface( 13940ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13950ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 13960ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1400076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 14026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 14036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1404e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 14056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 14076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 14088b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1409ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); 1410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1413a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1414a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 14171293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 14181293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 142096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1422118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1423118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian layer = createScreenshotSurface(client, d, w, h, flags); 1424118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1427076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 142896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1429285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 143096f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 14338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 143496f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 1436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1438a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1439b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 14401c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1441b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 144296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1448b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1449f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 145096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 14511c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1461a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1462a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 14638f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1464a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1469a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1470a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1471a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1472a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 147396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1474f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 147599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1476e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1482b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1483f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 148496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 148696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1491118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1492118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1493118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1494118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 14999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 15009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 15019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 15029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 15038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 15040aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 15050aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 15060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 15079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 15089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 150948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 15100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 151196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1512b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 151448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 151548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 151648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 151748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 15189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 15199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 15209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 15219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1524759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1531ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1533ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1534ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1535e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1537f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1538e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1541ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1544698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 154596f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1560698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1565698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1583698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1584698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1585698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1586698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1587f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1588f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1589f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1590f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1592698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian return flags; 1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1597b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() { 15988e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("Screen about to return, flinger = %p", this); 15991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1600b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 160122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1602b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 160522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 16068acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1609b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 16108e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 16111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1612b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 161322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1614b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1616b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 16198e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16338e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1634b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1635b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1648b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16511d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 165499b49840d309727678b77403d6cc9f920111623fMathias Agopian 165599b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 16629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 16639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 16709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 16718b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 16739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 167882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 167925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 168025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 168425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 168535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 168725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 169082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 169182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 169235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 169425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 169525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 169825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 169935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 170025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 170382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 170482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 170648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 170882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 170948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 171182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 171448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 171525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 172625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 172882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 173548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 173782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1749ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 175025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 175125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 176825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1778bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 178082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1790bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1794ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 18021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 18061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 180882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 18101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 181282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1817d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 18191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian eglQueryString(hw.getEGLDisplay(), 182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 182182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 182273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 182482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1834c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1837b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1838b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 184082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1841c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1844b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1845b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian HWComposer& hwc(hw.getHwComposer()); 186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 186682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ()); 187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1886698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 188959119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 18918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 18928e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1897a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 189899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 189999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1900e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1901375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1902375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 19051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 191299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 191399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1914e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 19151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 19161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1924b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 192599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1926375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1927375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1928375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1929e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1930375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 193501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 193635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 194153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 194253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 194553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1946cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1947cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1950cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 19534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 19554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 195653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 195753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 196153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1962a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1963a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1967a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 196901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1972b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 197312839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 19771b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 198653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 19871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display 19880dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 19890dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 199099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 199153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 199253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 19930dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 19940dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 20040dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 200659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2007118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 2008118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2013118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 201659119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 201722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 201822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 20231b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2036a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2037a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2041015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 20449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 205359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2055c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2056c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2059a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2060a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 20613b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 20651b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 206759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2068118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 2069118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 207359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 207959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 208159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2082ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 2083ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 2110ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21141b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 2117a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 211859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 2121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 212559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 2127a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2132b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2133b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2138ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 2139ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 2153ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 21549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2178ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2179ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2181ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 219059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2196ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2197ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 22009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2203ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2204ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2206ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2207ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2211ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 22129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2217a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2218a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2222a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 22239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2231ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2232ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 22359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 223859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 225559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 225659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 22589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2269ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2270ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2272ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2282a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2283c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 22849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 22961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 22989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2314b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2315b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 23169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 23179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 233859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2369ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2370ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2371a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2372a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 23739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 23749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2384ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2385ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2387ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 23889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 23899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2394a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 23969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 240359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2404ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2405ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2406ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 24079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 240859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 24109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 242859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 242959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 24319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 243259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2433a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2434c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 243559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2441abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 244322ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 244422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 24451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 24469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 24479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 24507ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 24517ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian hw.getHwComposer().disable(); 24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 24547ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 24557ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2456abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2457abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2464abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2465015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 246759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 246859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 247059119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2472abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 247459119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2475abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2476abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 247759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 247859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2483abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 248559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 248759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2488abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 249059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 24929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 24959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2496abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 249759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 249859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 250059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2503abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 25049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 25079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2510abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2511abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2512abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2513a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2514a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2515a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 251699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2517a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2518015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 25199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2525abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 25279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2528abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2529abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 25309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2536abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 25389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 25409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2541abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 25469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 254774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 254874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2550bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2551bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 255274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2553fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2554fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 255574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 255674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 255774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 25583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { 255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 256674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 25671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 256974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25713b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 25723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (hw.getSecureLayerVisible()) { 25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 25763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 257774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 258074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25849d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 25851c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2586c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 258774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 258874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2595fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 259774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2602c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 260474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 260974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2610ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 261274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 261574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2616f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 26179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 26189575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 261974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 262074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2621b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2622b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2624b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 26251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 2626b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2627bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 262874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 262974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2642fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 264474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2667e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2668e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2669e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 26709d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2671c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 267274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 267374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 26771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 267874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2679bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2680bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 26811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 26821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 268399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 26851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 269674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 269774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2698bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2699bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 27001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 27011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 27021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 270374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2704bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2705bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2708bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2709bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 27101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 271774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2718bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 27191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 27201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2724bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 27331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2734b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2740b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 27417303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 274396f0819f81293076e652792794a961543e6750d7Mathias Agopian 27449a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 27459a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27469a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 27479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2749d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 27509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 27519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2752d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2754d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2755d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2756d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2757e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2759a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 27609a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 27619a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 27629a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 27639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 27669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2768