SurfaceFlinger.cpp revision 8630320433bd15aca239522e54e711ef6372ab07
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 <stdint.h> 20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 23921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <GLES/gl.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 35d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h> 36921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h> 38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 41d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/gui/SharedBufferStack.h> 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 5190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 521b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.h" 53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 54d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 58118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 62a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 65bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID 0x3143 66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 7699b49840d309727678b77403d6cc9f920111623fMathias Agopian 7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 8228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis mTransationPending(false), 83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 87abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 9073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 91a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 963330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface(EGL_NO_SURFACE) 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 99a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1038afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1073854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING 1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian DdmConnection::start(getServiceName()); 1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1135df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else 1145df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled" 1153854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif 1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 117a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugRegion, "showupdates enabled"); 118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // Wait for the main thread to be done with its initialization 12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mReadyToRunBarrier.wait(); 12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 135a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // reset screen orientation 14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian Vector<ComposerState> state; 1468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian Vector<DisplayState> displays; 1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian DisplayState d; 1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian d.orientation = eOrientationDefault; 1498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian displays.add(d); 1508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian setTransactionState(state, displays, 0); 15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 153a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1567303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1617e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 16496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 16596f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 16696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 16796f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 177b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 182a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1833330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 189921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 193a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 194a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 195a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 198921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 199921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian GLuint texture; 201921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 202921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageDestroyGLTexture(GLuint texture) 203921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : texture(texture) { 204921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 205921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 206921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian glDeleteTextures(1, &texture); 207921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 208921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 209921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 210921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(texture)); 211921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 212921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat( 214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay dpy, 215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint const* attrs, 216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian PixelFormat format, 217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* outConfig) 218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config = NULL; 220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint numConfigs = -1, n=0; 221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigs(dpy, NULL, 0, &numConfigs); 222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig* const configs = new EGLConfig[numConfigs]; 223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian for (int i=0 ; i<n ; i++) { 225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint nativeVisualId = 0; 226a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); 227a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (nativeVisualId>0 && format == nativeVisualId) { 228a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian *outConfig = configs[i]; 229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NO_ERROR; 231a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian delete [] configs; 234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return NAME_NOT_FOUND; 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 237a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // it is to be used with WIFI displays 240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLConfig config; 241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint dummy; 242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian status_t err; 243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint attribs[] = { 244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_RECORDABLE_ANDROID, EGL_TRUE, 246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE 247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (err) { 250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // maybe we failed because of EGL_RECORDABLE_ANDROID 251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); 252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian attribs[2] = EGL_NONE; 253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); 254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); 256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { 257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return config; 260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 262a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Also create our EGLContext 264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint contextAttributes[] = { 265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority 266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY 267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority" 268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif 271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGL_NONE, EGL_NONE 272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }; 273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return ctxt; 276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) { 279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext); 280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!result) { 281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Couldn't create a working GLES context. check logs. exiting..."); 282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian extensions.initWithGLStrings( 287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VENDOR), 288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_RENDERER), 289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_VERSION), 290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetString(GL_EXTENSIONS), 291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VENDOR), 292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_VERSION), 293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQueryString(display, EGL_EXTENSIONS)); 2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint w, h; 296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_WIDTH, &w); 297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglQuerySurface(display, surface, EGL_HEIGHT, &h); 2988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 3017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 3038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian struct pack565 { 310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian inline uint16_t operator() (int r, int g, int b) const { 311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return (r<<11)|(g<<5)|b; 312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } pack565; 314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 3179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 3279575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 3289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glGenTextures(1, &mProtectedTexName); 3299575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 3309575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3319575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3329575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3339575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3349575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 3359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 340ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian // put the origin in the left-bottom corner 341ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // print some debugging info 344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLint r,g,b,a; 345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGL informations:"); 350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getEglVendor()); 351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getEglVersion()); 352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getEglExtension()); 353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("OpenGL ES informations:"); 356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("version : %s", extensions.getVersion()); 359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopiansurface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const { 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mServerCblk; 366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun() 369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{ 370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create the shared control-block 374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize EGL 383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglInitialize(display, NULL, NULL); 385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // Initialize the main display 387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // create native window to main display 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian sp<FramebufferSurface> anw = FramebufferSurface::create(); 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ANativeWindow* const window = anw.get(); 390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian if (!window) { 391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGE("Display subsystem failed to initialize. check logs. exiting..."); 392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian exit(0); 393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian } 394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize the config and context 396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian int format; 397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian window->query(window, NATIVE_WINDOW_FORMAT, &format); 398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig = selectEGLConfig(display, format); 399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLContext = createGLContext(display, mEGLConfig); 400a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 401a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize our main display hardware 402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig); 403a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mDisplayHardwares[0] = hw; 404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // initialize OpenGL ES 406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLSurface surface = hw->getEGLSurface(); 407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian initializeGL(display, surface); 408d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 4098630320433bd15aca239522e54e711ef6372ab07Mathias Agopian // initialize the H/W composer 4108630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mHwc = new HWComposer(this, 4118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian *static_cast<HWComposer::EventHandler *>(this), 4128630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hw->getRefreshPeriod()); 4138630320433bd15aca239522e54e711ef6372ab07Mathias Agopian if (mHwc->initCheck() == NO_ERROR) { 4148630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mHwc->setFrameBuffer(display, surface); 4158630320433bd15aca239522e54e711ef6372ab07Mathias Agopian } 4168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 417d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian // start the EventThread 418d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mEventThread = new EventThread(this); 4198aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian mEventQueue.setEventThread(mEventThread); 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian // We're now ready to accept clients... 422d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian mReadyToRunBarrier.open(); 423d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 424a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 425a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 4268b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 430a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 431a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 432a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 433a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 434a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 435a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 436a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const { 437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxTextureSize; 438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 439a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 440a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const { 441a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian return mMaxViewportDims[0] < mMaxViewportDims[1] ? 442a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mMaxViewportDims[0] : mMaxViewportDims[1]; 443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 444a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 446d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 447582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 448582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis const sp<ISurfaceTexture>& surfaceTexture) const { 449134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 450582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 451134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the visible layer list for the ISurface 453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t count = currentLayers.size(); 455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<count ; i++) { 456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(currentLayers[i]); 457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 458582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 459582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // Check the layers in the purgatory. This check is here so that if a 467582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // SurfaceTexture gets destroyed before all the clients are done using it, 468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis // the error will not be reported as "surface XYZ is not authenticated", but 469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // will instead fail later on when the client tries to use the surface, 470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // which should be reported as "surface XYZ returned an -ENODEV". The 471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // purgatorized layers are no less authentic than the visible ones, so this 472134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis // should not cause any harm. 473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis size_t purgatorySize = mLayerPurgatory.size(); 474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis for (size_t i=0 ; i<purgatorySize ; i++) { 475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 477582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbc != NULL) { 478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 479582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis if (lbcBinder == surfaceTextureBinder) { 480582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis return true; 481582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis } 482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis } 484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis return false; 486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 488d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 489d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 490d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 4918aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 492bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 493bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { 4951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface result = EGL_NO_SURFACE; 4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian EGLSurface old_surface = EGL_NO_SURFACE; 4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian sp<SurfaceTextureClient> stc; 4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (display != NULL) { 5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian stc = new SurfaceTextureClient(display); 5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian result = eglCreateWindowSurface(hw.getEGLDisplay(), 503a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mEGLConfig, (EGLNativeWindowType)stc.get(), NULL); 5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGE_IF(result == EGL_NO_SURFACE, 5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian "eglCreateWindowSurface failed (ISurfaceTexture=%p)", 5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian display.get()); 5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian { // scope for the lock 5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian old_surface = mExternalDisplaySurface; 5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplayNativeWindow = stc; 5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian mExternalDisplaySurface = result; 5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian ALOGD("mExternalDisplaySurface = %p", result); 5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian if (old_surface != EGL_NO_SURFACE) { 5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // Note: EGL allows to destroy an object while its current 5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian // it will fail to become current next time though. 5203094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian eglDestroySurface(hw.getEGLDisplay(), old_surface); 5213094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian } 5223094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5233094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 5243094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const { 5253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian Mutex::Autolock _l(mStateLock); 5263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian return mExternalDisplaySurface; 5273094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian} 5283094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 54599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 55099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 55299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 55399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 55499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 55699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 55799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 55899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 55999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() { 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 56399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return true; 56499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5668630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) { 5678630320433bd15aca239522e54e711ef6372ab07Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 5688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hw.onVSyncReceived(timestamp); 5698630320433bd15aca239522e54e711ef6372ab07Mathias Agopian mEventThread->onVSyncReceived(dpy, timestamp); 5708630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 5718630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 5728630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) { 5738630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().eventControl(event, enabled); 5748630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 5758630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 5771c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 5804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 5834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 5864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 5874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 5914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 5924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian uint32_t transactionFlags = peekTransactionFlags(mask); 5934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 5944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 5954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransaction(transactionFlags); 5964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 5974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 5984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 5994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 6024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 6034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handlePageFlip(); 6044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 6054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion |= dirtyRegion; 6064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 6073a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 6084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 6094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRefresh(); 610a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (mVisibleRegionsDirty) { 6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region opaqueRegion; 6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Region dirtyRegion; 6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion); 6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mDirtyRegion.orSelf(dirtyRegion); 6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian /* 6193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian * rebuild the visible layer list per screen 6203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian */ 6213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: iterate through all displays 6233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); 6243b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian Vector< sp<LayerBase> > layersSortedByZ; 6263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const size_t count = currentLayers.size(); 6273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian for (size_t i=0 ; i<count ; i++) { 6283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!currentLayers[i]->visibleRegion.isEmpty()) { 6293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // TODO: also check that this layer is associated to this display 6303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layersSortedByZ.add(currentLayers[i]); 6313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.setVisibleLayersSortedByZ(layersSortedByZ); 6343b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // FIXME: mWormholeRegion needs to be calculated per screen 6373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here 6383b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mWormholeRegion = Region(hw.getBounds()).subtract( 6393b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hw.getTransform().transform(opaqueRegion) ); 6403b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty = false; 6413b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian invalidateHwcGeometry(); 6423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 6433b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen, we should check all of them 6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (mDirtyRegion.isEmpty()) { 6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return; 6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 649303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: iterate through all displays 6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const DisplayHardware& hw(getDisplayHardware(0)); 65269a655caef30663403802281210363f643ceb946Mathias Agopian 6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: dirtyRegion should be per screen 6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region into this screen's coordinate space 6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& planeTransform(hw.getTransform()); 6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion = planeTransform.transform(mDirtyRegion); 6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDirtyRegion.andSelf(hw.bounds()); 659303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian 660b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_UNLIKELY(mHwWorkListDirty)) { 6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // build the h/w work list 6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleWorkList(hw); 6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6653094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (CC_LIKELY(hw.canDraw())) { 6674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // repaint the framebuffer (if needed) 6684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleRepaint(hw); 6694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // inform the h/w that we're done compositing 6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian postFramebuffer(); 6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // pretend we did the post 6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 6754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 6763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // render to the external display if we have one 6784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface externalDisplaySurface = getExternalDisplaySurface(); 6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (externalDisplaySurface != EGL_NO_SURFACE) { 6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLSurface cur = eglGetCurrentSurface(EGL_DRAW); 6814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(), 6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian externalDisplaySurface, externalDisplaySurface, 6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian eglGetCurrentContext()); 6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> external failed"); 6864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (success) { 6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // redraw the screen entirely... 6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDisable(GL_TEXTURE_2D); 6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClearColor(0,0,0,1); 6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 6934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glMatrixMode(GL_MODELVIEW); 6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glLoadIdentity(); 6953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 6963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); 6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = layers.size(); 6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; ++i) { 6994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian layer->drawForSreenShot(hw); 7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface); 7044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "external display eglSwapBuffers failed"); 7053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 7064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian hw.compositionComplete(); 7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian 7094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian success = eglMakeCurrent(eglGetCurrentDisplay(), 7104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian cur, cur, eglGetCurrentContext()); 7114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 7124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian ALOGE_IF(!success, "eglMakeCurrent -> internal failed"); 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 719841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 720b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // mSwapRegion can be empty here is some cases, for instance if a hidden 721b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // or fully transparent window is updating. 722b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // in that case, we need to flip anyways to not risk a deadlock with 723b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian // h/w composer. 724b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 7251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 7268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 7273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 7283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian size_t numLayers = layers.size(); 729a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 730a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 731c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 732c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (hwc.initCheck() == NO_ERROR) { 733c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 734c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall const HWComposer::LayerListIterator end = hwc.end(); 735c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 736c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall if (cur->getCompositionType() == HWC_OVERLAY) { 7373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->setAcquireFence(*cur); 738c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } else { 739c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall cur->setAcquireFenceFd(-1); 740c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 741c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 742c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall } 743c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 744a44b04163957d6086362f6f365443c4c93379031Mathias Agopian hw.flip(mSwapRegion); 7458630320433bd15aca239522e54e711ef6372ab07Mathias Agopian hwc.commit(); 746e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 747ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 748ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall HWComposer::LayerListIterator cur = hwc.begin(); 749ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall const HWComposer::LayerListIterator end = hwc.end(); 750ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { 7513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(&*cur); 752ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 753ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 754ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall for (size_t i = 0; i < numLayers; i++) { 7553b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian layers[i]->onLayerDisplayed(NULL); 756ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 757e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 758e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 759a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 760a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 761a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mSwapRegion.clear(); 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 766841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 767841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 772ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 773ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 774ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 775ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 776ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 777ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 778ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 779ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 780ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 781ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian transactionFlags = getTransactionFlags(mask); 7824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion = handleTransactionLocked(transactionFlags); 783ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 784ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 785ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 786ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 787ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 7884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 7894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 7903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 7933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 7944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 7953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 806076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const int dpy = 0; // TODO: should be a parameter 8261b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); 82798a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian hw.setOrientation(mCurrentState.orientation); 828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8291b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware? 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 8400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 8410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 84248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 8440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 8453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 8463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 8480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 8490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could traverse the tree from front to back and compute the actual visible region 8514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // TODO: we could cache the transformed region 8524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Layer::State front(layer->drawingState()); 8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region visibleReg = front.transform.transform( 8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region(Rect(front.active.w, front.active.h))); 8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf(visibleReg); 8560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 8570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 8624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 8634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 8674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 8684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 8694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 8704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 8714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 8734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 8754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 8764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransationPending = false; 8774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 8811bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 883841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 884841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian dirtyRegion.clear(); 890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 893076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 896970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 900ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 908ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 910ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 911ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 916ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 917ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 91999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 920a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const bool translucent = !layer->isOpaque(); 9214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Rect bounds(layer->computeBounds()); 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 923ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 924ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 925ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 9264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region transparentRegionScreen; 9274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 9284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 9294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 9304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 9314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = tr.transform(s.transparentRegion); 9324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 9344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 9354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen.clear(); 9364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 9384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian transparentRegionScreen = s.transparentRegion; 9394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian visibleRegion.subtractSelf(transparentRegionScreen); 941ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 943ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 9444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 948ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 949ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 953ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 955ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 956ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 9674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 970a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 973ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 974ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 975ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 976ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 977ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 978ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 979ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 980ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 981a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 9844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 985ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 986ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 993ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 9958b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip() 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10061c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 10074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 100899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 10091bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 10124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const size_t count = currentLayers.size(); 10134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 10144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 10154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const sp<LayerBase>& layer(layers[i]); 10164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) ); 10174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 10193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 10200dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return dirtyRegion; 1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1024ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1025ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1026ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1027ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1028ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh() 103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian bool needInvalidate = false; 103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 103399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const size_t count = currentLayers.size(); 103499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian for (size_t i=0 ; i<count ; i++) { 103599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (layer->onPreComposition()) { 103799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian needInvalidate = true; 103899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 103999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 104099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (needInvalidate) { 104199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalLayerUpdate(); 104299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 104399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 104499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 104599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 10461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw) 1047a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 1048a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 10498630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 1050a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 10513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); 1052a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 1053a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 10543e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian 10553e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 10563e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 10573e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 10584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian currentLayers[i]->setGeometry(hw, *cur); 105953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian if (mDebugDisableHWC || mDebugRegion) { 10603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian cur->setSkip(true); 106173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 1062a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1063a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 1064a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 1065b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 10661b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw) 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1068841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1069841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1070b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 10710656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(mDebugRegion)) { 10741b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian debugFlashRegions(hw); 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1077b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 1078b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 1079b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 1082a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 108329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 108429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 108529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 1086a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 108895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 108929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1090df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 109195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 109229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 10930656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mDirtyRegion.set(mSwapRegion.bounds()); 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 109529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 10970656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian mSwapRegion = mDirtyRegion; 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian setupHardwareComposer(hw); 11021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, mDirtyRegion); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 11059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian mSwapRegion.orSelf(mDirtyRegion); 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) 1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 11123e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 11133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 11143e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur == end) { 11159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian return; 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1117a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 11183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 111945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 1120a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1121e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(hwc.getNumLayers() != count, 112245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 112345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 1124a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 112545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 112624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 112724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 112824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 1129a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 113045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 113145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 113245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 113345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 11343e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1135f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer->setPerFrameData(*cur); 1137f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian } 1138f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian status_t err = hwc.prepare(); 1139e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 1140f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian} 1141f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian 11421b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) 1143f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{ 11448630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 11453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian HWComposer::LayerListIterator cur = hwc.begin(); 11463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian const HWComposer::LayerListIterator end = hwc.end(); 1147cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian 1148cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 11493e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (cur==end || fbLayerCount) { 1150a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 115145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 1152b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (hwc.getLayerCount(HWC_OVERLAY)) { 1153b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1154b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1155b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 1156b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // GPUs doing a "clean slate" glClear might be more efficient. 1157b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 1158b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClearColor(0, 0, 0, 0); 1159b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1160b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1161b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 1162b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian if (!mWormholeRegion.isEmpty()) { 1163b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 1164b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian drawWormhole(); 1165b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 11674b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 1168a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian /* 1169a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian * and then, render the layers targeted at the framebuffer 1170a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian */ 11714b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 11723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 1173a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const size_t count = layers.size(); 11744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& tr = hw.getTransform(); 1175a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall for (size_t i=0 ; i<count ; ++i) { 1176a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian const sp<LayerBase>& layer(layers[i]); 11774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 1178a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!clip.isEmpty()) { 1179a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end && cur->getCompositionType() == HWC_OVERLAY) { 11803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) 1181a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian && layer->isOpaque()) { 1182b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // never clear the very first layer since we're 1183b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // guaranteed the FB is already cleared 11841b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->clearWithOpenGL(hw, clip); 1185a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 11866ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall ++cur; 1187a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian continue; 1188a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1189a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // render the layer 11901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->draw(hw, clip); 11914b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1192a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall if (cur != end) { 1193a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall ++cur; 1194a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 11954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 11964b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw) 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 12010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 120253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian const int32_t height = hw.getHeight(); 12030656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian if (mSwapRegion.isEmpty()) { 120453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return; 120553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian } 12060a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1207a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian if (!(flags & DisplayHardware::SWAP_RECTANGLE)) { 12080a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 12090a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 12101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian composeSurfaces(hw, repaint); 12110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 12120a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 1213c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1214c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 12180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 12190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 12200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 12210926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 12220a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 12230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 122520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 122620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 122720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 122820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 123053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.top }, 123153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.left, height - r.bottom }, 123253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.bottom }, 123353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian { r.right, height - r.top } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 12390656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian hw.flip(mSwapRegion); 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 12420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1251f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 1252b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glDisable(GL_TEXTURE_2D); 1253f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDisable(GL_BLEND); 1254b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian glColor4f(0,0,0,0); 1255f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian 1256f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian GLfloat vertices[4][2]; 1257f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glVertexPointer(2, GL_FLOAT, 0, vertices); 1258f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator it = region.begin(); 1259f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian Region::const_iterator const end = region.end(); 1260f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian while (it != end) { 1261f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian const Rect& r = *it++; 1262f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][0] = r.left; 1263f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[0][1] = r.top; 1264f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][0] = r.right; 1265f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[1][1] = r.top; 1266f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][0] = r.right; 1267f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[2][1] = r.bottom; 1268f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][0] = r.left; 1269f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian vertices[3][1] = r.bottom; 1270f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1271f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian } 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 127496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 127596f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 12761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 127796f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 12784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian size_t name = client->attachLayer(lbc); 12794f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 128096f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1281921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1282921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 128396f0819f81293076e652792794a961543e6750d7Mathias Agopian 12844f113740180b6512b43723c4728f262882dc9b45Mathias Agopian return ssize_t(name); 128596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 128696f0819f81293076e652792794a961543e6750d7Mathias Agopian 128796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 128896f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 128996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 129096f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 129196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 129296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 129396f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1296076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 13079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 130876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 13109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 131176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 131276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 131376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 13148c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 13152f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall mLayersPendingRemoval.push(layerBase); 13160b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 13173d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 13183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 131996f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 132096f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 13229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1324dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1325dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{ 1326dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1327dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1328dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 133899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 13458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 13468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 13478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 13488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 1349698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 1350cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 13518b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian int orientation = eOrientationUnchanged; 13528b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian if (displays.size()) { 13538b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian // TODO: handle all displays 13548b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian orientation = displays[0].orientation; 13558b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian } 13568b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian 135728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (mCurrentState.orientation != orientation) { 1359b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis mCurrentState.orientation = orientation; 136128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= eTransactionNeeded; 1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } else if (orientation != eOrientationUnchanged) { 136332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("setTransactionState: ignoring unrecognized orientation: %d", 1364b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis orientation); 1365b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1366b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1367b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const size_t count = state.size(); 1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1370698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1371698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 137228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis transactionFlags |= setClientStateLocked(client, s.state); 1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 137528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 137728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1378698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = true; 1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian while (mTransationPending) { 1385386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 138932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1390386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian mTransationPending = false; 1391386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1392386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1393cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1397921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer( 13980ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian ISurfaceComposerClient::surface_data_t* params, 13990ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 14000ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1404076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> surfaceHandle; 14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 14076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1408921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 14096e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 14106e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 14116e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 14128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1413921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createNormalLayer(client, d, w, h, flags, format); 1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 14191293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 14201293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 1422921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createDimLayer(client, d, w, h, flags); 1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1424118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian case eFXSurfaceScreenshot: 1425921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian layer = createScreenshotLayer(client, d, w, h, flags); 1426118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian break; 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 143096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1431285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 143296f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 14348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 143596f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 1436a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian params->identity = layer->getIdentity(); 14371c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 143896f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1444921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer( 1445f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 144696f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 14471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1456a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1457a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1458a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 14598f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1464a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1465a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1466a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1467a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 146996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1470f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 147199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_LIKELY(err != NO_ERROR)) { 1472921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1478921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer( 1479f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 148096f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 148296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1483118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return layer; 1484118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1485118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1486921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client, DisplayID display, 1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1494921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 14959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 14969a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 14979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 14989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 14998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 15000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 15010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 15020aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 15039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 15049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 150548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 15060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 150796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 1508b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 150948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 151048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 151148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 151248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 15149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 15159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 15169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 15179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1518921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1520759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian sp<LayerBaseClient> l(layer.promote()); 1523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 1524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian err = removeLayer_l(l); 1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (err == NAME_NOT_FOUND) { 1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // The surface wasn't in the current list, which means it was 1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // removed already, which means it is in the purgatory, 1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // and need to be removed from there. 1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian ssize_t idx = mLayerPurgatory.remove(l); 1531e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(idx < 0, 1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 1533f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1534e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 1537ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1540698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 154196f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1542698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const layer_state_t& s) 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer != 0) { 1547698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const uint32_t what = s.what; 1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & ePositionChanged) { 1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setPosition(s.x, s.y)) 1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eLayerChanged) { 1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setLayer(s.z)) { 1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // we need traversal (state changed) 1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian // AND transaction (list changed) 1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eSizeChanged) { 1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setSize(s.w, s.h)) { 1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eAlphaChanged) { 1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1569698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eMatrixChanged) { 1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setMatrix(s.matrix)) 1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eTransparentRegionChanged) { 1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (what & eVisibilityChanged) { 1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian flags |= eTraversalNeeded; 1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1583f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (what & eCropChanged) { 1584f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (layer->setCrop(s.crop)) 1585f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis flags |= eTraversalNeeded; 1586f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 15878785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian if (what & eLayerStackChanged) { 15888785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian if (layer->setLayerStack(s.layerStack)) 15898785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian flags |= eTraversalNeeded; 15908785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian } 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 16008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().acquire(); 1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.acquireScreen(); 160222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenAcquired(); 1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // this is a temporary work-around, eventually this should be called 1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // by the power-manager 1605b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 160622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian // from this point on, SF will process updates again 16078acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian repaintEverything(); 1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1610b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() { 16118e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross ALOGD("About to give-up screen, flinger = %p", this); 16121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware 1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian if (hw.isScreenAcquired()) { 161422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian mEventThread->onScreenReleased(); 1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian hw.releaseScreen(); 16168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().release(); 1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian // from this point on, SF will stop drawing 1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 16218e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() { 1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { } 1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenAcquired(); 1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1631b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(this); 1632b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16358e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() { 1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian SurfaceFlinger* flinger; 1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } 1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian flinger->onScreenReleased(); 1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(this); 1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian postMessageSync(msg); 1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 1648b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1649b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 1650b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 16531d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 165699b49840d309727678b77403d6cc9f920111623fMathias Agopian 165799b49840d309727678b77403d6cc9f920111623fMathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 16709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 16738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 16769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 16779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 16789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 168425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 168525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian listLayersLocked(args, index, result, buffer, SIZE); 168735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 169025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 169125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpStatsLocked(args, index, result, buffer, SIZE); 169435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 169825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 169925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 170025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian clearStatsLocked(args, index, result, buffer, SIZE); 170135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 170225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian dumpAllLocked(result, buffer, SIZE); 170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 170848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 171148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 171648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian result.append(buffer); 172625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 172725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 172825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 173748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty()) { 174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (name.isEmpty() || (name == layer->getName())) { 174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dumpStats(result, buffer, SIZE); 174882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 174982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 175082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 1751ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8& result, char* buffer, size_t SIZE) const 175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 176925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 177025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked( 177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8& result, char* buffer, size_t SIZE) const 177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1780bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->dump(result, buffer, SIZE); 179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 1792bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the layers in the purgatory 179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 1796ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t purgatorySize = mLayerPurgatory.size(); 179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<purgatorySize ; i++) { 180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 180282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian layer->shortDump(result, buffer, SIZE); 180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 18041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 18121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVendor(), 181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getRenderer(), 181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian extensions.getVersion()); 181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 1819d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EGL : %s\n", 18211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian eglQueryString(hw.getEGLDisplay(), 182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian EGL_VERSION_HW_ANDROID)); 182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 182473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mWormholeRegion.dump(result, "WormholeRegion"); 182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " orientation=%d, canDraw=%d\n", 183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mCurrentState.orientation, hw.canDraw()); 183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, 183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 1836c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 183782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 1839b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " y-dpi : %f\n" 1840b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian " density : %f\n", 184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 1843c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getRefreshRate(), 184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.getDpiX(), 1846b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDpiY(), 1847b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian hw.getDensity()); 184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mEventThread->dump(result, buffer, SIZE); 186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 18668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, "h/w composer state:\n"); 186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append(buffer); 18733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ()); 187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hw.dump(result); 1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1888698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 18938e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 18948e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1899a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 190099b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 190199b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1902e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1903375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1904375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 19121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 19131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 191499b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 191599b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1916e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 19181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 19191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 19201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1926b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 192799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1928375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1929375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1930375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1931e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 1932375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 193701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 193835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 194353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 194453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 194753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1950cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1951cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1952cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 19554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 19564d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 19574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 196153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 196253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 196353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 1967a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 1968a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 1969a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 197101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1974b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 197512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 19791b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 198853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 19891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display 19900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian const Rect bounds(hw.getBounds()); 19910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian setInvalidateRegion(Region(bounds)); 199299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 199353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 199453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) { 19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion = reg; 19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() { 20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Mutex::Autolock _l(mInvalidateLock); 20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Region reg(mInvalidateRegion); 20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian mInvalidateRegion.clear(); 20040dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian return reg; 20050dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian} 20060dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian 200759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 200859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian Mutex::Autolock _l(mStateLock); 2013118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 2014118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2015118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 201922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 202022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 20251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 203759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 2038a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2039a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2043015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 204459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 205159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 205559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 2057c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 2058c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2061a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2062a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 20633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 20671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 206959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2070118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian hw.compositionComplete(); 2071118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 207559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 208159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 208359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter { 2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian DisplayEventReceiver::Event buffer[4]; 2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<Looper> looper; 2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<IDisplayEventConnection> events; 2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian sp<BitTube> eventTube; 2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic: 2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter(const sp<EventThread>& eventThread) { 2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper = new Looper(true); 2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events = eventThread->createEventConnection(); 2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube = events->getDataChannel(); 2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0); 2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian void wait() { 2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian ssize_t n; 2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian looper->pollOnce(-1); 2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // we don't handle any errors here, it doesn't matter 2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // and we don't want to take the risk to get stuck. 2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // drain the events... 2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian while ((n = DisplayEventReceiver::getEvents( 2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian eventTube, buffer, 4)) > 0) ; 2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian events->requestNextVsync(); 2110ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian } 2111ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian}; 2112ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 21161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 2119a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const Region screenBounds(hw.getBounds()); 212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 2123118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 212759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 2129a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2134b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2135b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian /* 2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * Texture coordinate mapping 2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * u 2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1 +----------+---+ 2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | | | image is inverted 2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | V | | w.r.t. the texture 2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 1-v +----------+ | coordinates 2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * | | 2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 +--------------+ 2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 0 1 2153ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian * 2154ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian */ 2155ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2181ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2182ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2183ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 219259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[0] = x; vtx[1] = y; 2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[2] = x; vtx[3] = y + h; 2200ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 2201ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian vtx[6] = x + w; vtx[7] = y; 22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2205ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2206ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian char value[PROPERTY_VALUE_MAX]; 2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian property_get("debug.sf.electron_frames", value, "24"); 2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian int nbFrames = (atoi(value) + 1) >> 1; 2211ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian if (nbFrames <= 0) // just in case 2212ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian nbFrames = 24; 2213ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian 22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_TEXTURE); 2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2222a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glMatrixMode(GL_MODELVIEW); 2223a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian glLoadIdentity(); 2224a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian 22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2234ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2235ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 224059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 225759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 225859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2272ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2273ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2274ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 2284a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2285c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 22981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDefaultDisplayHardware()); 22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2316b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2317b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 234059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2371ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian VSyncWaiter vsync(mEventThread); 2372ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2373a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 2374a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 2387ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2388ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2389ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2396a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 240559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2406ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian // wait for vsync 2407ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian vsync.wait(); 2408ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian 24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 241059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 24279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 24289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 243059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 243159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 24339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 243459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 2435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glDisable(GL_TEXTURE_2D); 2436c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_BLEND); 243759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2443abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 24449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 244522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian ATRACE_CALL(); 244622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian 24471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 24499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 24509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 24519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // turn off hwc while we're doing the animation 24548630320433bd15aca239522e54e711ef6372ab07Mathias Agopian getHwComposer().disable(); 24557ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian // and make sure to turn it back on (if needed) next time we compose 24567ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian invalidateHwcGeometry(); 24577ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian 2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2464abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2465abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2466abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2467015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 246859119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 247059119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2474abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 247559119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 247659119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2477abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2478abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2485abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 248759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 248859119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2490abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 249259119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 249359119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 24959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 24969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 24979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2498abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 250059119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 250159119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 250259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2505abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware())); 25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 25099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 25109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2512abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2513abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2514abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2515a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2516a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2517a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 251899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2519a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2520015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2527abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 25289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 25299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2530abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2531abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2538abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 25409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 25419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2543abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 25469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 25479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 25489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 255074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 255174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2552bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2553bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2555fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2556fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 255774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 25603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { 256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) { 256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 25663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 256774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 25691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(getDisplayHardware(dpy)); 257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 257174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 257274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian // if we have secure windows on this display, never allow the screen capture 25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (hw.getSecureLayerVisible()) { 25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian return PERMISSION_DENIED; 25763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 25773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 25783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) { 257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 25803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 258474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 258574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 25869d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 25871c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian // sw, sh, minLayerZ, maxLayerZ); 2588c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 259574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2597fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2604c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 260974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 261074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 2612ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian glOrthof(0, hw_w, hw_h, 0, 0, 1); 261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 261574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 261674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 261774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2618f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 26199575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const LayerVector& layers(mDrawingState.layersSortedByZ); 26209575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis const size_t count = layers.size(); 262174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 262274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t flags = layer->drawingState().flags; 2624b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (!(flags & ISurfaceComposer::eLayerHidden)) { 2625b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian const uint32_t z = layer->drawingState().z; 2626b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 26271b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian layer->drawForSreenShot(hw); 2628b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian } 2629bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 2644fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 266774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2669e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2670e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2671e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 26729d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2673c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 267674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 267774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 26781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 26791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 268074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2681bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2682bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 268599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 26961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 26971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 269874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 269974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2700bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2701bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 27021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 27031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 27041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 270574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2706bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2709bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2710bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2711bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 271974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2720bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2726bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 27331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 27341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 27351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2736921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2737921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2738921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2739921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2740921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : SortedVector<sp<LayerBase> >(rhs) { 2741921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2742921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2743921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2744921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2746921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2747921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2748921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian // sort layers by Z order 2749921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t lz = l->currentState().z; 2750921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian uint32_t rz = r->currentState().z; 2751921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian // then by sequence, so we get a stable ordering 2752921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence); 2753921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2754921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2755921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 2756921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2757921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::State::State() 2758921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian : orientation(ISurfaceComposer::eOrientationDefault), 2759921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian orientationFlags(0) { 2760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 27617303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2762b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 276396f0819f81293076e652792794a961543e6750d7Mathias Agopian 27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 27679a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2769d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian PixelFormat format, uint32_t usage, status_t* error) { 27709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 27719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 2772d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian *error = err; 2773a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (err != 0 || graphicBuffer->handle == 0) { 2774d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian if (err == NO_MEMORY) { 2775d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian GraphicBuffer::dumpAllocationsToSystemLog(); 2776d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian } 2777e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2778a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian "failed (%s), handle=%p", 2779a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian w, h, strerror(-err), graphicBuffer->handle); 27809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 27819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 27829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 27839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 27849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 27859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 27869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2788