SurfaceFlinger.cpp revision a6546e5af4ce0cff01cd13605fc3eb16325feac3
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 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h> 4135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h> 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h> 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h> 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h" 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h" 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header 58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id 59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */ 60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS 61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003 62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif 63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCount(0), 73cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending(false), 74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mHardwareTest("android.permission.HARDWARE_TEST"), 77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"), 781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian mReadFramebuffer("android.permission.READ_FRAME_BUFFER"), 79375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mDump("android.permission.DUMP"), 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole(false), 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay(false), 83abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode(0), 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount(0), 85bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplayTime(0), 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground(0), 889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 923330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mConsoleSignals(0), 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("SurfaceFlinger is starting"); 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = atoi(value); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugRegion, "showupdates enabled"); 11178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugBackground, "showbackground enabled"); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return graphicPlane(0).displayHardware().getOverlayEngine(); 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1247303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1297e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 13196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 13296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 13396f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 13496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 13596f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection() 141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<ISurfaceComposerClient> bclient; 143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<UserClient> client(new UserClient(this)); 144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t err = client->initCheck(); 145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (err == NO_ERROR) { 146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian bclient = client; 147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return bclient; 149b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 150b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 151b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 169a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1703330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 171a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.stop", "bootanim"); 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef() 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Wait for the main thread to be done with its initialization 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.wait(); 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI( "SurfaceFlinger's main thread ready to run. " 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2097303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2107303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_PACK_ALIGNMENT, 4); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t textureData[4] = { g0, g1, g1, g0 }; 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glOrthof(0, w, h, 0, 0, 1); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerDim::initDimmer(this, w, h); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.open(); 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 269a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 271a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent() 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t timeout = -1; 2850408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t freezeDisplayTimeout = ms2ns(5000); 286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (UNLIKELY(isFrozen())) { 287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // wait 5 seconds 288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t now = systemTime(); 289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mFreezeDisplayTime == 0) { 290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mFreezeDisplayTime = now; 291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian timeout = waitTime>0 ? waitTime : 0; 294bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project } 295f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 296bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // see if we timed out 2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (isFrozen()) { 3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t now = systemTime(); 3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian nsecs_t frozenTime = (now - mFreezeDisplayTime); 3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (frozenTime >= freezeDisplayTimeout) { 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we timed out and are still frozen 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay, mFreezeCount); 3060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = 0; 308bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplay = false; 3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (msg != 0) { 3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian switch (msg->what) { 3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian case MessageQueue::INVALIDATE: 3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // invalidate message, just return to the main loop 3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian return; 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() { 323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mEventQueue.invalidate(); 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const { 327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // this is the IPC call 328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const_cast<SurfaceFlinger*>(this)->signalEvent(); 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return mEventQueue.postMessage(msg, reltime, flags); 335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime, flags); 341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (res == NO_ERROR) { 342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian msg->wait(); 343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 344bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // check for transactions 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mConsoleSignals)) { 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleConsoleEvents(); 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(mTransactionCount == 0)) { 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if we're in a global transaction, don't do anything. 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t transactionFlags = getTransactionFlags(mask); 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(transactionFlags)) { 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleTransaction(transactionFlags); 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // post surfaces (if needed) 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handlePageFlip(); 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 3758a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian if (LIKELY(hw.canDraw() && !isFrozen())) { 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // repaint the framebuffer (if needed) 37735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 37835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = hw.getCurrentBufferIndex(); 37935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog& logger(GraphicLog::getInstance()); 38035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 38135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT, index); 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleRepaint(); 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian // inform the h/w that we're done compositing 38535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 38674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian hw.compositionComplete(); 38774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // release the clients before we flip ('cause flip might block) 38935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index); 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockClients(); 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project postFramebuffer(); 39435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 39535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT_DONE, index); 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pretend we did the post 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockClients(); 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project usleep(16667); // 60 fps period 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!mInvalidRegion.isEmpty()) { 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 4089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 4099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = now; 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.flip(mInvalidRegion); 4119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime = systemTime() - now; 4129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = 0; 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidRegion.clear(); 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents() 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something to do with the console 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int what = android_atomic_and(0, &mConsoleSignals); 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleAcquired) { 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.acquireScreen(); 4259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // this is a temporary work-around, eventually this should be called 4269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager 427abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (mDeferReleaseConsole && hw.isScreenAcquired()) { 43162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // We got the release signal before the acquire signal 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = false; 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleReleased) { 43759119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (hw.isScreenAcquired()) { 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = true; 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4493d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian Vector< sp<LayerBase> > ditchedLayers; 4503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 4514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 4524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * Perform and commit the transaction 4534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 4544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 4553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian { // scope for the lock 4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian Mutex::Autolock _l(mStateLock); 4579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 4589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction = now; 4593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian handleTransactionLocked(transactionFlags, ditchedLayers); 4609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime = systemTime() - now; 4619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction = 0; 4624da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian // here the transaction has been committed 4633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 4654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 4664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * Clean-up all layers that went away 4674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * (do this without the lock held) 4684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 4693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = ditchedLayers.size(); 4703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 4710852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian if (ditchedLayers[i] != 0) { 4720852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian //LOGD("ditching layer %p", ditchedLayers[i].get()); 4730852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian ditchedLayers[i]->ditch(); 4740852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian } 4753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked( 4793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers) 4803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 4813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 513c08731e756868653d09d3e49b723706df3687070Mathias Agopian const uint32_t type = mCurrentState.orientationType; 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freezing or unfreezing the display -> trigger animation if needed 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay = mCurrentState.freezeDisplay; 531064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian if (mFreezeDisplay) 532064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian mFreezeDisplayTime = 0; 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 54348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian ditchedLayers.add(layer); 5525d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 571ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 586970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 609970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool translucent = layer->needsBlending(); 611970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 647a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 658a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 677970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 683970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 684970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 685970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 686970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 695cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = false; 696cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool visibleRegions = mVisibleRegionsDirty; 702000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian LayerVector& currentLayers = const_cast<LayerVector&>( 703000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian mDrawingState.layersSortedByZ); 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegions |= lockPageFlip(currentLayers); 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region screenRegion(hw.bounds()); 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (visibleRegions) { 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian size_t count = currentLayers.size(); 7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 756b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 759b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 760b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.orSelf(mDirtyRegion); 761b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian if (mInvalidRegion.isEmpty()) { 762b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // nothing to do 763b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian return; 764b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian } 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mDebugRegion)) { 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 770b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 771b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 772b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 773b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 776df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian if ((flags & DisplayHardware::SWAP_RECTANGLE) || 777df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED)) 778df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 77929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 78029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 78129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 78229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 78429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 78529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian mDirtyRegion.set(mInvalidRegion.bounds()); 78629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 78729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 78829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 78929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 79029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 79129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 79395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 79429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 795df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 79695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 79729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(mInvalidRegion.bounds()); 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 80029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidRegion = mDirtyRegion; 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compose all surfaces 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // clear the dirty regions 810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(!mWormholeRegion.isEmpty())) { 816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // should never happen unless the window manager has a bug 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // draw something... 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawWormhole(); 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 8204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 821000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian const size_t count = layers.size(); 822000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian for (size_t i=0 ; i<count ; ++i) { 82345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 82645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 82745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 82845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients() 832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = drawingLayers.size(); 835076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* const layers = drawingLayers.array(); 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; ++i) { 837076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = layers[i]; 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->finishPageFlip(); 839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 8440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 8450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 8460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 8470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 8480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 8490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 8500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 8510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 8520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 8530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 8540a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian TextureManager::deactivateTextures(); 855df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 8610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 8620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 8630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 8640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 8650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 8660926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 86820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 86920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 87020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 87120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.top }, 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.bottom }, 875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.bottom }, 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.top } 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 8810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 882b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian if (mInvalidRegion.isEmpty()) { 883b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mDirtyRegion.dump("mDirtyRegion"); 884b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.dump("mInvalidRegion"); 885b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian } 886b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian hw.flip(mInvalidRegion); 887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 8890a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //mDirtyRegion.dump("mDirtyRegion"); 893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!mDebugBackground)) { 9090a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 91020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 91120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 91220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 91320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 9257f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external) 9261f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (GLExtensions::getInstance().haveTextureExternal()) { 9271f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 9281f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 9290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif 930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 93620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 93720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 93820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 93920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const 949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mFrameCount; 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mLastFrameCount = 0; 952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static nsecs_t mLastFpsTime = 0; 953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static float mFps = 0; 954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameCount++; 955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t now = systemTime(); 956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t diff = now - mLastFpsTime; 957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (diff > ms2ns(250)) { 958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFpsTime = now; 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFrameCount = mFrameCount; 961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: mFPS has the value we want 963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 965076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 973076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 975f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 9761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 9771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 9781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 97996f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 98096f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 9811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 98296f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 98396f0819f81293076e652792794a961543e6750d7Mathias Agopian 98496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 98596f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t name = client->attachLayer(lbc); 98696f0819f81293076e652792794a961543e6750d7Mathias Agopian 98796f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 98896f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 98996f0819f81293076e652792794a961543e6750d7Mathias Agopian 99096f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 99196f0819f81293076e652792794a961543e6750d7Mathias Agopian} 99296f0819f81293076e652792794a961543e6750d7Mathias Agopian 99396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 99496f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 99596f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 99696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 99796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 99896f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 99996f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1002076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1004b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1005b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 1006b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.removeItem( lbc->getSurface()->asBinder() ); 1007b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1010076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10133d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 10179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 10188c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian // remove the layer from the main list (through a transaction). 10199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 10208c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 10210b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian layerBase->onRemoved(); 10220b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 10233d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 10243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 102596f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 102696f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 10279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 10289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 10299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 103096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 103296f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 103396f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 103496f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1042bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 1046bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian signalEvent(); 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction() 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&mTransactionCount); 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction() 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (android_atomic_dec(&mTransactionCount) == 1) { 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1060cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 1061cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // if there is a transaction with a resize, wait for it to 1062cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // take effect before returning. 1063cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mStateLock); 1064cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian while (mResizeTransationPending) { 1065448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1066448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1067448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // just in case something goes wrong in SF, return to the 1068448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // called after a few seconds. 1069448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1070448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian mResizeTransationPending = false; 1071448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian break; 1072448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian } 1073cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 1; 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 108762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 0; 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 110162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1105c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy, 1106c08731e756868653d09d3e49b723706df3687070Mathias Agopian int orientation, uint32_t flags) 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != orientation) { 1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1114c08731e756868653d09d3e49b723706df3687070Mathias Agopian mCurrentState.orientationType = flags; 1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation = orientation; 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCV.wait(mStateLock); 1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project orientation = BAD_VALUE; 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return orientation; 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 112596f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, 11267e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian const String8& name, ISurfaceComposerClient::surface_data_t* params, 1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1130076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<LayerBaseClient::Surface> surfaceHandle; 11326e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 11336e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 11346e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 11356e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 11366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 11376e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 11386e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(flags & ePushBuffers)) { 114496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createPushBuffersSurface(client, d, w, h, flags); 1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian layer = normalLayer; 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 115196f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createBlurSurface(client, d, w, h, flags); 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 115496f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1158076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 115996f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1160285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 116196f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1162b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 11641c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian if (surfaceHandle != 0) { 116596f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 11661c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->identity = surfaceHandle->getIdentity(); 11671c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->width = w; 11681c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->height = h; 11691c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->format = format; 1170b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1171b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1172b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.add(surfaceHandle->asBinder(), normalLayer); 1173b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 11741c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1175b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 117696f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1182b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1183f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 118496f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 11851c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1194a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1195a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1196a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 11978f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1198a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1202a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1203a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1204a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1205a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1206a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 120796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1208f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 120996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (LIKELY(err != NO_ERROR)) { 1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1211076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1216b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface( 1217f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 121896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 122096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBlur> layer = new LayerBlur(this, display, client); 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1225b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1226f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 122796f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 122996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1234b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface( 1235f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 123696f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 123896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBuffer> layer = new LayerBuffer(this, display, client); 1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 124396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 12449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 12459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 12469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 12479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 12480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * 12490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 12500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 12510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 12529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 12539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 125448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 12550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 125696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 125748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 125848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 125948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 126048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 126148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 12629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 12639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 12649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 12659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 12669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer) 1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1268759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 12699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 1270f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian class MessageDestroySurface : public MessageBase { 12710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger; 1272f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian sp<LayerBaseClient> layer; 1273f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian public: 12740aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian MessageDestroySurface( 12750aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer) 12760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian : flinger(flinger), layer(layer) { } 1277f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian virtual bool handler() { 1278cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian sp<LayerBaseClient> l(layer); 1279cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian layer.clear(); // clear it outside of the lock; 1280f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 1281759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian /* 1282759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * remove the layer from the current list -- chances are that it's 1283759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * not in the list anyway, because it should have been removed 1284759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * already upon request of the client (eg: window manager). 1285759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * However, a buggy client could have not done that. 1286759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * Since we know we don't have any more clients, we don't need 1287759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * to use the purgatory. 1288759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian */ 1289cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian status_t err = flinger->removeLayer_l(l); 12908c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian LOGE_IF(err<0 && err != NAME_NOT_FOUND, 12918c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return true; 1293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian }; 12953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 1296bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian postMessageAsync( new MessageDestroySurface(this, layer) ); 1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState( 130196f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t count, 1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const layer_state_t* states) 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<count ; i++) { 130896f0819f81293076e652792794a961543e6750d7Mathias Agopian const layer_state_t& s(states[i]); 130996f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1310076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t what = s.what; 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & ePositionChanged) { 1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setPosition(s.x, s.y)) 1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eLayerChanged) { 1317f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setLayer(s.z)) { 1319f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1320f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.add(layer); 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need traversal (state changed) 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // AND transaction (list changed) 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTransactionNeeded|eTraversalNeeded; 1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eSizeChanged) { 1327cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (layer->setSize(s.w, s.h)) { 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1329cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = true; 1330cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eAlphaChanged) { 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eMatrixChanged) { 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setMatrix(s.matrix)) 1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eTransparentRegionChanged) { 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setTransparentRegionHint(s.transparentRegion)) 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eVisibilityChanged) { 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setFlags(s.flags, s.mask)) 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags) { 1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(flags); 1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t SIZE = 1024; 1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 1375375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (!mDump.checkCalling()) { 1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 13829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 13839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // figure out if we're stuck somewhere 13849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 13859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 13869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 13879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 13889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 13899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 13909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 13919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 13929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 13939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 13949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 13959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 13969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 13979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 13989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 13999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 14009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 14019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 14029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 14081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 14091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian layer->dump(result, buffer, SIZE); 14101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const Layer::State& s(layer->drawingState()); 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.transparentRegion.dump(result, "transparentRegion"); 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion.dump(result, "WormholeRegion"); 1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay?"yes":"no", mFreezeCount, 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation, hw.canDraw()); 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 14239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 14249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last eglSwapBuffers() time: %f us\n" 14259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last transaction time : %f us\n", 14269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); 14279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 14299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inSwapBuffersDuration || !locked) { 14309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 14319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inSwapBuffersDuration/1000.0); 14329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 14359795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inTransactionDuration || !locked) { 14369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 14379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inTransactionDuration/1000.0); 14389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 14413330b203039dea366d4981db1408a460134b2d2cMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian alloc.dump(result); 14439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 14449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (locked) { 14459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mStateLock.unlock(); 14469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project write(fd, result.string(), result.size()); 1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case OPEN_GLOBAL_TRANSACTION: 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CLOSE_GLOBAL_TRANSACTION: 1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case FREEZE_DISPLAY: 1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case UNFREEZE_DISPLAY: 1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 146359119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 14649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1469a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 1470375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { 1471375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1472375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1473375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 14761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 14771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 14781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 14791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 14801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 14811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 14821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 14831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) { 14841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian LOGE("Permission Denial: " 14851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 14861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 14871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 14881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1494b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 1495375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (UNLIKELY(!mHardwareTest.checkCalling())) { 1496375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1497375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1498375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1499375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1500375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 150501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 150635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe 1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1521cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1522cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1523cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1524cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 152735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1006:{ // enable/disable GraphicLog 152835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int enabled = data.readInt32(); 152935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog::getInstance().setEnabled(enabled); 153035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return NO_ERROR; 153135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian } 1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1007: // set mFreezeCount 1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = data.readInt32(); 15340408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 153701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 155459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 15559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 15569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 155759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 155859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 155959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 156059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 156159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 156259119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 156359119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 156459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 156559119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 156659119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 156759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 156859119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 156959119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 157059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 157159119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 157259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 157359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 157459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 15759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 15769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 157759119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1578015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 157959119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 158059119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 15819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 15829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 158359119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 158459119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 158559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 158659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 158759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 15889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 15899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 159059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 15919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 15929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 15939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 15949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 15959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 15969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 15979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 15989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 15999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 160059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 16029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 16039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 16049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 160559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 16079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 16089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 16099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 16109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 161159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 161359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 16159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 16169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 161759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 16199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 162059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 16229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 16239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 16249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 16259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 162659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 16289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 16299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 16309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 16319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 16329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 163359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 16359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 16369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 16379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 16389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 16399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 16409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 16419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 16429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 16439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 16449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 16459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 16469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 16479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 16489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 16499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 16509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 16519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 16529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 16539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 16549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 16559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 16569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 16579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 16589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 16599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 16609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 16619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 16629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 16639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 16649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 16659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 16669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 16679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 16689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 16699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 16709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 16719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 16729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 16739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 16749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 16759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 16769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 16779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 16789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 16799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 16809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 168159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 16829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 16839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 16859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 16869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 16879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 16889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 16899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 16919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 16929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 16939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 16949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 16959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const int nbFrames = 12; 16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 16989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 17019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 17029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 17059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 17079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 17089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 171359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 17159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 17219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 17229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 173059119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 173159119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 17329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 17359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 17419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 17539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 17569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 17839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 181159119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1842a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 1843a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1861a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1904abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 1911abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 1912abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 1913abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 1914abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 1915abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 1916abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 1917abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 1918abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1919abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 1920abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 1921abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 1922015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(false); 1923015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 192459119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 192659119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 192759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 192859119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 192959119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 1930abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 193159119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 193259119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 1933abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 1934abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 193559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 193659119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 193759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 193859119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 193959119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 194059119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 1941abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 194259119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 194359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 194459119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1946abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 194759119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 194859119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 194959119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 1954abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 195559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 195659119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 195759119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 195859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 1960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1961abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 1968abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 1969abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 1970abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 1971015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(true); 1972a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 1973a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 1974a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 1975a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian signalEvent(); 1976a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 1977015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 1984abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 1987abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 1988abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 1995abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2000abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2006df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 2007df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian sp<IMemoryHeap>* heap, 2008df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2009df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t sw, uint32_t sh) 2010df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian{ 2011df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian status_t result = PERMISSION_DENIED; 2012df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2013df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // only one display supported for now 2014df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 2015df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian return BAD_VALUE; 2016df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2017df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 2018df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian return INVALID_OPERATION; 2019df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2020df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // get screen geometry 2021df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 2022df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const uint32_t hw_w = hw.getWidth(); 2023df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const uint32_t hw_h = hw.getHeight(); 2024df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2025df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if ((sw > hw_w) || (sh > hw_h)) 2026df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian return BAD_VALUE; 2027df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2028df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian sw = (!sw) ? hw_w : sw; 2029df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian sh = (!sh) ? hw_h : sh; 2030df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const size_t size = sw * sh * 4; 2031df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2032df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // make sure to clear all GL error flags 2033df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 2034df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2035df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // create a FBO 2036df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian GLuint name, tname; 2037df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glGenRenderbuffersOES(1, &tname); 2038df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 2039df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2040df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glGenFramebuffersOES(1, &name); 2041df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 2042df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 2043df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 2044df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2045df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2046df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 2047df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2048df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 2049df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glViewport(0, 0, sw, sh); 2050df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glMatrixMode(GL_PROJECTION); 2051df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glPushMatrix(); 2052df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glLoadIdentity(); 2053df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glOrthof(0, hw_w, 0, hw_h, 0, 1); 2054df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glMatrixMode(GL_MODELVIEW); 2055df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2056df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // redraw the screen entirely... 2057df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glClearColor(0,0,0,1); 2058df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2059df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 2060df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const size_t count = layers.size(); 2061df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 2062df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian const sp<LayerBase>& layer(layers[i]); 2063df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian layer->drawForSreenShot(); 2064df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } 2065df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2066df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // XXX: this is needed on tegra 2067df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glScissor(0, 0, sw, sh); 2068df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2069df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // check for errors and return screen capture 2070df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (glGetError() != GL_NO_ERROR) { 2071df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // error while rendering 2072df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian result = INVALID_OPERATION; 2073df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } else { 2074df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // allocate shared memory large enough to hold the 2075df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // screen capture 2076df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian sp<MemoryHeapBase> base( 2077df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 2078df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian void* const ptr = base->getBase(); 2079df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (ptr) { 2080df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // capture the screen with glReadPixels() 2081df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 2082df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian if (glGetError() == GL_NO_ERROR) { 2083df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian *heap = base; 2084df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian *w = sw; 2085df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian *h = sh; 2086df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 2087df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian result = NO_ERROR; 2088df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } 2089df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } else { 2090df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian result = NO_MEMORY; 2091df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } 2092df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } 2093df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2094df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glEnable(GL_SCISSOR_TEST); 2095df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glViewport(0, 0, hw_w, hw_h); 2096df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glMatrixMode(GL_PROJECTION); 2097df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glPopMatrix(); 2098df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glMatrixMode(GL_MODELVIEW); 2099df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2100df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2101df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } else { 2102df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian result = BAD_VALUE; 2103df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian } 2104df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2105df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian // release FBO resources 2106df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 2107df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glDeleteRenderbuffersOES(1, &tname); 2108df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian glDeleteFramebuffersOES(1, &name); 2109df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian return result; 2110df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian} 2111df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 2112df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian 21131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 21141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 2115df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2116df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t sw, uint32_t sh) 21171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 21181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 21191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 21201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 21211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 21231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 21241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 21261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 21271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 21281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 21291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 21301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 21311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 2132df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t sw; 2133df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t sh; 21341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 21351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 21361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 2137df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2138df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian uint32_t sw, uint32_t sh) 21391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2140df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED) 21411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 21421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 21431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 21441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 21451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 21461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 21471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 21481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 21501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 21511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 21521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2153df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian result = flinger->captureScreenImplLocked(dpy, 2154df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian heap, w, h, f, sw, sh); 21551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 21571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 21581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 21591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2161df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian dpy, heap, width, height, format, sw, sh); 21621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 21631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 21641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 21651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 21661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 21671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 21681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 21701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2171b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2173b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2174b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2175b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2176b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2177b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 21787303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2179b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 218096f0819f81293076e652792794a961543e6750d7Mathias Agopian 2181b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2182b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 218696f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 218796f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 218896f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 218996f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 219096f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 219196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 219296f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 219396f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2196076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 219796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2198b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2200076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 220196f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2203b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = android_atomic_inc(&mNameGenerator); 220496f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 220596f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2208b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 220996f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 221096f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 221196f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 221296f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 221396f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 221496f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 221596f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 221696f0819f81293076e652792794a961543e6750d7Mathias Agopian } 221796f0819f81293076e652792794a961543e6750d7Mathias Agopian } 221896f0819f81293076e652792794a961543e6750d7Mathias Agopian} 2219076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const { 2220076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 222196f0819f81293076e652792794a961543e6750d7Mathias Agopian const wp<LayerBaseClient>& layer(mLayers.valueFor(i)); 222296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 222396f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 222496f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2225076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2226076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 222996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const { 2230b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2231b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2232b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const { 2233b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return -1; 2234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 223596f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 2236b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2237b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2238b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 224196f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->createSurface(this, pid, name, params, 224296f0819f81293076e652792794a961543e6750d7Mathias Agopian display, w, h, format, flags); 2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 224496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 224596f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->removeSurface(this, sid); 2246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 224796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) { 224896f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->setClientState(this, count, states); 2249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2252b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger) 2254b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : ctrlblk(0), mBitmap(0), mFlinger(flinger) 2255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2256b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int pgsize = getpagesize(); 2257b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); 2258b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2259b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mCblkHeap = new MemoryHeapBase(cblksize, 0, 2260b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian "SurfaceFlinger Client control-block"); 2261b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); 2263b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { // construct the shared structure in-place. 2264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian new(ctrlblk) SharedClient; 2265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2266b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2267b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2268b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient() 2269b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2270b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { 2271b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk->~SharedClient(); // destroy our shared-structure. 2272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2273b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2274b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * When a UserClient dies, it's unclear what to do exactly. 2276b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * We could go ahead and destroy all surfaces linked to that client 2277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * however, it wouldn't be fair to the main Client 2278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * (usually the the window-manager), which might want to re-target 2279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * the layer to another UserClient. 2280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * I think the best is to do nothing, or not much; in most cases the 2281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * WM itself will go ahead and clean things up when it detects a client of 2282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * his has died. 2283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * The remaining question is what to display? currently we keep 2284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * just keep the current buffer. 2285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const { 2289b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return ctrlblk == 0 ? NO_INIT : NO_ERROR; 2290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer) 2293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = layer->getToken(); 2295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (name >= 0) { 2296579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian int32_t mask = 1LU<<name; 2297579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { 2298579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); 2299579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const { 2304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mCblkHeap; 2305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const 2308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = NAME_NOT_FOUND; 2310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> layer(mFlinger->getLayer(sur)); 2311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (layer == 0) return name; 2312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2313579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // if this layer already has a token, just return it 2314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = layer->getToken(); 2315579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if ((name >= 0) && (layer->getClient() == this)) 2316579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return name; 2317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = 0; 2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian do { 2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t mask = 1LU<<name; 2321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { 2322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // we found and locked that name 2323579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian status_t err = layer->setToken( 2324579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const_cast<UserClient*>(this), ctrlblk, name); 2325579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (err != NO_ERROR) { 2326579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // free the name 2327579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian android_atomic_and(~mask, &mBitmap); 2328579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian name = err; 2329579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2330b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian break; 2331b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2332b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (++name > 31) 2333b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = NO_MEMORY; 2334b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } while(name >= 0); 2335b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 233653503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)", 233753503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian // sur->asBinder().get(), name, this, mBitmap); 2338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return name; 2339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface( 2342b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2343b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2344b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2345b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian uint32_t flags) { 2346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2347b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) { 2349b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2350b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2351b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) { 2352b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2353b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2354b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2355b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 23712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 23752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 23762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 23772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 23782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 23792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 23802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 23812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 23822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 23832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 23842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 23852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 23862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 23872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 23882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 23892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 23902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 23912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 23922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 23932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 23942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 23952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 23962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 23972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 23982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 23992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 24002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 24012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 24022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 24032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 24042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 24052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 24062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 24072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 24082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 24092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2415eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2416eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2419eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2420eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2422eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2425eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2428eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2433eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 24412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 24432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 24442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 24452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 24462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 24472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2449eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2450eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2451eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2452eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2453eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2455eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 24560d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 24572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 246559119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 246659119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 246759119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 246859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2474076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2480