SurfaceFlinger.cpp revision bf2c6a6c8f1df40ac94e28b948754bb9739daaca
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 "LayerDim.h" 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 54a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header 57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id 58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */ 59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS 60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003 61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif 62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BnSurfaceComposer(), Thread(false), 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCount(0), 72cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending(false), 73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 75375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mHardwareTest("android.permission.HARDWARE_TEST"), 76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"), 771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian mReadFramebuffer("android.permission.READ_FRAME_BUFFER"), 78375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian mDump("android.permission.DUMP"), 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 80a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(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), 8873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 933330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished(false), 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mConsoleSignals(0), 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer(0) 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project init(); 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init() 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("SurfaceFlinger is starting"); 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = atoi(value); 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugRegion, "showupdates enabled"); 11278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian LOGI_IF(mDebugBackground, "showbackground enabled"); 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDeleteTextures(1, &mWormholeTexName); 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1207303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian return mServerHeap; 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1257e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 12796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 12896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 12996f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 13096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 13196f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection() 137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<ISurfaceComposerClient> bclient; 139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<UserClient> client(new UserClient(this)); 140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t err = client->initCheck(); 141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (err == NO_ERROR) { 142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian bclient = client; 143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return bclient; 145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 1658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1663330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 167a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.stop", "bootanim"); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef() 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Wait for the main thread to be done with its initialization 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.wait(); 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI( "SurfaceFlinger's main thread ready to run. " 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1977303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 1987303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 1997303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 2007303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t textureData[4] = { g0, g1, g1, g0 }; 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glOrthof(0, w, h, 0, 0, 1); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerDim::initDimmer(this, w, h); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.open(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 265a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 266a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 2678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent() 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 279f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 280f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t timeout = -1; 2810408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t freezeDisplayTimeout = ms2ns(5000); 282f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (UNLIKELY(isFrozen())) { 283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // wait 5 seconds 284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t now = systemTime(); 285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mFreezeDisplayTime == 0) { 286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mFreezeDisplayTime = now; 287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian timeout = waitTime>0 ? waitTime : 0; 290bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project } 291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 292bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 2930408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 2940408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // see if we timed out 2950408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (isFrozen()) { 2960408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t now = systemTime(); 2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian nsecs_t frozenTime = (now - mFreezeDisplayTime); 2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (frozenTime >= freezeDisplayTimeout) { 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we timed out and are still frozen 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay, mFreezeCount); 3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = 0; 304bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplay = false; 3050408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3080408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (msg != 0) { 3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian switch (msg->what) { 3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian case MessageQueue::INVALIDATE: 3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // invalidate message, just return to the main loop 3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian return; 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() { 319f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mEventQueue.invalidate(); 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const { 323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // this is the IPC call 324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const_cast<SurfaceFlinger*>(this)->signalEvent(); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 327bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 328bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 330bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return mEventQueue.postMessage(msg, reltime, flags); 331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime, flags); 337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (res == NO_ERROR) { 338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian msg->wait(); 339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // check for transactions 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mConsoleSignals)) { 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleConsoleEvents(); 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(mTransactionCount == 0)) { 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if we're in a global transaction, don't do anything. 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t transactionFlags = getTransactionFlags(mask); 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(transactionFlags)) { 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleTransaction(transactionFlags); 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // post surfaces (if needed) 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handlePageFlip(); 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 370a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (UNLIKELY(mHwWorkListDirty)) { 371a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // build the h/w work list 372a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian handleWorkList(); 373a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 374a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 3768a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian if (LIKELY(hw.canDraw() && !isFrozen())) { 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // repaint the framebuffer (if needed) 37835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 37935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = hw.getCurrentBufferIndex(); 38035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog& logger(GraphicLog::getInstance()); 38135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 38235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT, index); 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleRepaint(); 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian // inform the h/w that we're done compositing 38635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 38774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian hw.compositionComplete(); 38874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 38935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 3908392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala postFramebuffer(); 3918392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala 392c479e18db0216f7096fefe85ffa71ab00329aef3Mathias Agopian logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index); 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockClients(); 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 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; 462a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = true; 4634da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian // here the transaction has been committed 4643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 4664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 4674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * Clean-up all layers that went away 4684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * (do this without the lock held) 4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 470a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = ditchedLayers.size(); 4723d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 4730852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian if (ditchedLayers[i] != 0) { 4740852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian //LOGD("ditching layer %p", ditchedLayers[i].get()); 4750852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian ditchedLayers[i]->ditch(); 4760852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian } 4773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked( 4813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers) 4823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 4833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 515c08731e756868653d09d3e49b723706df3687070Mathias Agopian const uint32_t type = mCurrentState.orientationType; 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freezing or unfreezing the display -> trigger animation if needed 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay = mCurrentState.freezeDisplay; 533064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian if (mFreezeDisplay) 534064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian mFreezeDisplayTime = 0; 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 54548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5483d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5493d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5533d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian ditchedLayers.add(layer); 5545d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 588970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 611970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool translucent = layer->needsBlending(); 613970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 649a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 660a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 672ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 6748b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 679970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 685970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 686970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 688970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = false; 698cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool visibleRegions = mVisibleRegionsDirty; 704a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian LayerVector& currentLayers( 705a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const_cast<LayerVector&>(mDrawingState.layersSortedByZ)); 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegions |= lockPageFlip(currentLayers); 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region screenRegion(hw.bounds()); 710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (visibleRegions) { 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian size_t count = currentLayers.size(); 7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 728a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = true; 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 752076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 754b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 759a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 760a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 761a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 762a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 763a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 764a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 765a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 766a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 76745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 76845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 76945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 77073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian if (mDebugDisableHWC) { 77173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 77273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 77373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 774a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 775a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 777b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 780b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 781b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.orSelf(mDirtyRegion); 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mDebugRegion)) { 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 787b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 789b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 790b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 7938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 7948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 795df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 79629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 79729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 79829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 79929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 800b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 80129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 80229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian mDirtyRegion.set(mInvalidRegion.bounds()); 80329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 80429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 80529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 80629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 80729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 81095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 81129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 812df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 81395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 81429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(mInvalidRegion.bounds()); 816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 81729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidRegion = mDirtyRegion; 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compose all surfaces 824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // clear the dirty regions 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(!mWormholeRegion.isEmpty())) { 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // should never happen unless the window manager has a bug 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // draw something... 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawWormhole(); 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 837a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 838a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian status_t err = NO_ERROR; 8394da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 84045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 841a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 842a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 843a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(hw.getHwComposer()); 84445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 845a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 84645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian LOGE_IF(cur && hwc.getNumLayers() != count, 84745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 84845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 849a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 85045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 85124925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 85224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 85324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 854a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 85545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 85645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 85745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 85845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 85945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian Region transparent; 86045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur) { 86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 86245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 86345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->setPerFrameData(&cur[i]); 86445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur[i].hints & HWC_HINT_CLEAR_FB) { 86545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!(layer->needsBlending())) { 86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian transparent.orSelf(layer->visibleRegionScreen); 86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 868a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 87045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian err = hwc.prepare(); 87145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 873a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 87445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 87545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * clear the area of the FB that need to be transparent 87645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 877a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian transparent.andSelf(dirty); 878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (!transparent.isEmpty()) { 879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glClearColor(0,0,0,0); 880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian Region::const_iterator it = transparent.begin(); 881a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian Region::const_iterator const end = transparent.end(); 882a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const int32_t height = hw.getHeight(); 883a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian while (it != end) { 884a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Rect& r(*it++); 885a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const GLint sy = height - (r.top + r.height()); 886a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glScissor(r.left, sy, r.width(), r.height()); 887a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 888a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 89045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 89245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 89345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 89445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 89545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur) { 897586a0deb76012c4347298c11df460631853b67f8Antti Hatala if ((cur[i].compositionType != HWC_FRAMEBUFFER) && 898586a0deb76012c4347298c11df460631853b67f8Antti Hatala !(cur[i].flags & HWC_SKIP_LAYER)) { 89945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // skip layers handled by the HAL 90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian continue; 90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 90373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients() 913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = drawingLayers.size(); 916076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* const layers = drawingLayers.array(); 917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; ++i) { 918076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = layers[i]; 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->finishPageFlip(); 920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 9260a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 9270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 9280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 9290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 9300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 9310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 9320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 9330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 9340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 9350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian TextureManager::deactivateTextures(); 936df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian 937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 9420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 9430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 9440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 9450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 9460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 9470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 94920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 95020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 95120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 95220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.top }, 955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.bottom }, 956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.bottom }, 957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.top } 958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 9620a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 963b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian if (mInvalidRegion.isEmpty()) { 964b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mDirtyRegion.dump("mDirtyRegion"); 965b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.dump("mInvalidRegion"); 966b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian } 967b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian hw.flip(mInvalidRegion); 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 9700a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //mDirtyRegion.dump("mDirtyRegion"); 974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!mDebugBackground)) { 9900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 99120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 99220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 99320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 99420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 10067f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external) 10071f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (GLExtensions::getInstance().haveTextureExternal()) { 10081f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 10091f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 10100a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif 1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 101720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 101820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 101920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 102020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const 1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mFrameCount; 1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mLastFrameCount = 0; 1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static nsecs_t mLastFpsTime = 0; 1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static float mFps = 0; 1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameCount++; 1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t now = systemTime(); 1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t diff = now - mLastFpsTime; 1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (diff > ms2ns(250)) { 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFpsTime = now; 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFrameCount = mFrameCount; 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: mFPS has the value we want 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1046076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1054076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1056f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 10571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 10581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 10591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 106096f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 106196f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 10621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 106396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 106496f0819f81293076e652792794a961543e6750d7Mathias Agopian 106596f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 106696f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t name = client->attachLayer(lbc); 106796f0819f81293076e652792794a961543e6750d7Mathias Agopian 106896f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 106996f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 107096f0819f81293076e652792794a961543e6750d7Mathias Agopian 107196f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 107296f0819f81293076e652792794a961543e6750d7Mathias Agopian} 107396f0819f81293076e652792794a961543e6750d7Mathias Agopian 107496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 107596f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 107696f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 107796f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 107896f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 107996f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 108096f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1083076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1085b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1086b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 1087b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.removeItem( lbc->getSurface()->asBinder() ); 1088b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1091076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10943d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 10989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 10998c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian // remove the layer from the main list (through a transaction). 11009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 11018c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11020b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian layerBase->onRemoved(); 11030b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 110696f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 110796f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 111196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 111396f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 111496f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 111596f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1123bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 1127bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian signalEvent(); 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction() 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&mTransactionCount); 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction() 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (android_atomic_dec(&mTransactionCount) == 1) { 1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1141cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 11428b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber // if there is a transaction with a resize, wait for it to 1143cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // take effect before returning. 1144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mStateLock); 1145cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian while (mResizeTransationPending) { 1146448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1147448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1148448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // just in case something goes wrong in SF, return to the 1149448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // called after a few seconds. 1150448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1151448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian mResizeTransationPending = false; 1152448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian break; 1153448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian } 1154cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 1; 1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 116862b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 0; 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 118262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy, 1187c08731e756868653d09d3e49b723706df3687070Mathias Agopian int orientation, uint32_t flags) 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != orientation) { 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1195c08731e756868653d09d3e49b723706df3687070Mathias Agopian mCurrentState.orientationType = flags; 1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation = orientation; 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCV.wait(mStateLock); 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project orientation = BAD_VALUE; 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return orientation; 1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, 12077e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian const String8& name, ISurfaceComposerClient::surface_data_t* params, 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1211076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<LayerBaseClient::Surface> surfaceHandle; 12136e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12146e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 12156e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12166e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12198b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1221b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1224a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1225a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12281293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12291293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 123196f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1235076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 123696f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1237285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 123896f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1239b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 12418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 124296f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 12431c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->identity = surfaceHandle->getIdentity(); 12441c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->width = w; 12451c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->height = h; 12461c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->format = format; 1247b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1248b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1249b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.add(surfaceHandle->asBinder(), normalLayer); 1250b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 12511c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1252b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 125396f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1259b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1260f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 126196f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 12621c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1271a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1272a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1273a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 12748f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1275a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1279a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1280a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1281a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1282a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1283a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 128496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1285f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 128696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (LIKELY(err != NO_ERROR)) { 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1288076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1294f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 129596f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 129796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130296f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13078b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13080aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13100aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 131348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 131596f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 131648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 131748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 131848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 131948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 132048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 13259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer) 1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1327759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 13288b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian class MessageDestroySurface : public MessageBase { 13300aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger; 1331f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian sp<LayerBaseClient> layer; 1332f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian public: 13330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian MessageDestroySurface( 13340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer) 13350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian : flinger(flinger), layer(layer) { } 1336f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian virtual bool handler() { 1337cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian sp<LayerBaseClient> l(layer); 1338cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian layer.clear(); // clear it outside of the lock; 1339f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 1340759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian /* 13418b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * remove the layer from the current list -- chances are that it's 13428b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * not in the list anyway, because it should have been removed 13438b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * already upon request of the client (eg: window manager). 1344759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * However, a buggy client could have not done that. 1345759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * Since we know we don't have any more clients, we don't need 1346759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * to use the purgatory. 1347759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian */ 1348cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian status_t err = flinger->removeLayer_l(l); 13498c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian LOGE_IF(err<0 && err != NAME_NOT_FOUND, 13508c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1351f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return true; 1352f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1353f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian }; 13543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 1355bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian postMessageAsync( new MessageDestroySurface(this, layer) ); 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState( 136096f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t count, 1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const layer_state_t* states) 1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<count ; i++) { 136796f0819f81293076e652792794a961543e6750d7Mathias Agopian const layer_state_t& s(states[i]); 136896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1369076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t what = s.what; 1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & ePositionChanged) { 1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setPosition(s.x, s.y)) 1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eLayerChanged) { 1376f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setLayer(s.z)) { 1378f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1379f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.add(layer); 1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need traversal (state changed) 1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // AND transaction (list changed) 1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTransactionNeeded|eTraversalNeeded; 1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eSizeChanged) { 1386cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (layer->setSize(s.w, s.h)) { 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1388cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = true; 1389cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eAlphaChanged) { 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eMatrixChanged) { 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setMatrix(s.matrix)) 1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eTransparentRegionChanged) { 1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setTransparentRegionHint(s.transparentRegion)) 1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eVisibilityChanged) { 1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setFlags(s.flags, s.mask)) 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags) { 1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(flags); 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14311d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 1434375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (!mDump.checkCalling()) { 1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 14419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 14429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // figure out if we're stuck somewhere 14439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 14449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 14459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 14469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 14479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 14489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 14499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 14509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 14519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 14529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 14539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 14549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 14559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 14579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 14588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 14599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 14619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 14671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 14681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian layer->dump(result, buffer, SIZE); 14691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const Layer::State& s(layer->drawingState()); 1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.transparentRegion.dump(result, "transparentRegion"); 1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion.dump(result, "WormholeRegion"); 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay?"yes":"no", mFreezeCount, 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation, hw.canDraw()); 1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 14829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 14839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last eglSwapBuffers() time: %f us\n" 14849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last transaction time : %f us\n", 14859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); 14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 14889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inSwapBuffersDuration || !locked) { 14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inSwapBuffersDuration/1000.0); 14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inTransactionDuration || !locked) { 14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inTransactionDuration/1000.0); 14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 150073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 150173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 150273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 150373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC ? "disabled" : "enabled"); 150473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian result.append(buffer); 15058372785879d329f592f6883620b5a32d80d74691Mathias Agopian hwc.dump(result, buffer, SIZE); 150673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 15073330b203039dea366d4981db1408a460134b2d2cMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1508076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian alloc.dump(result); 15091d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling hw.dump(result); 15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (locked) { 15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mStateLock.unlock(); 15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project write(fd, result.string(), result.size()); 1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case OPEN_GLOBAL_TRANSACTION: 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CLOSE_GLOBAL_TRANSACTION: 1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case FREEZE_DISPLAY: 1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case UNFREEZE_DISPLAY: 1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 153059119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 15319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1536a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 1537375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { 1538375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1539375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1540375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 15431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 15441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 15451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 15461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 15471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 15481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 15491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 15501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) { 15511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian LOGE("Permission Denial: " 15521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 15531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 15541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 15551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1561b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 1562375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (UNLIKELY(!mHardwareTest.checkCalling())) { 1563375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1564375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1565375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1566375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1567375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 157201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 157335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 158373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian case 1008: // toggle use of hw composer 158473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian n = data.readInt32(); 158573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC = n ? 1 : 0; 158673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mHwWorkListDirty = true; 158773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian // fall-through... 1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe 1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1593cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1594cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1595cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1596cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1597cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 159935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1006:{ // enable/disable GraphicLog 160035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int enabled = data.readInt32(); 160135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog::getInstance().setEnabled(enabled); 160235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return NO_ERROR; 160335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian } 1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1007: // set mFreezeCount 1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = data.readInt32(); 16060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 160901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 162559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 162659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 16289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 162959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 163059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 163159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 163259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 163359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 163459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 163559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 163659119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 163759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 163859119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 163959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 164059119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 164159119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 164259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 164359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 164459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 164559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 164659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 16479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 164959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1650015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 165159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 165259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 16539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 165559119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 165659119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 165759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 165859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 165959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 16609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 16619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 166259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 16649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 16659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 16669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 16679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 16689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 16699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 16709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 16719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 167259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 16749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 16759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 16769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 167759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 16799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 16809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 16819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 16829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 168359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 168559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 16879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 16889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 168959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 16919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 169259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 16949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 16959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 169859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 17019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 17029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 170559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 17079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 17089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 17139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 17159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 17199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 17219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 17229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 17319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 17329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 17359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 17419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 175359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 17569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const int nbFrames = 12; 17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 17839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 178559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 180259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 180359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 188359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1914a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 1915a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1933a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 194259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 194459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 196459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 196559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 196959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 197059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1976abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 1983abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 1984abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 1985abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 1986abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 1987abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 1988abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 1989abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 1990abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1991abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 1992abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 1993abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 1994015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(false); 1995015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 199659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 199759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 199859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 199959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 200059119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 200159119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2002abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 200359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 200459119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2005abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2006abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 200759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 200859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 200959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 201059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 201159119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 201259119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2013abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 201459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 201659119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 201759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2018abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 20229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 20249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2026abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2033abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 20349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 20369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2040abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2041abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2042abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2043015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(true); 2044a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2045a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2046a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 2047a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian signalEvent(); 2048a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2049015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 20509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2056abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2059abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2060abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 20639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2067abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2072abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 207874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 207974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 208074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2081bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2082bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 208374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 208474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 208574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 208674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 208774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 208874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 208974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 209074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 209174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 209274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 209374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 209474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 209574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 209674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 209774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 209874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 209974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 210074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 210174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 210274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 210374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 210474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 210574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 210674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 210774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 210874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 210974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 211074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 211174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 211274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 211374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 211474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 211574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 211674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 211774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 211874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 211974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 212074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 212174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 212274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 212374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 212474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 212574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 212674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glOrthof(0, hw_w, 0, hw_h, 0, 1); 212774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 212874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 212974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 213074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 213174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 213274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 213374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t count = layers.size(); 213474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 213574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2136bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian const uint32_t z = layer->drawingState().z; 2137bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2138bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian layer->drawForSreenShot(); 2139bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 214074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 214174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 214274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 214374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 214474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 214574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 214674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 214774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 214874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 214974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 215074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 215174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 215274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 215374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 215474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 215574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 215674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 215774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 215874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 215974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 216074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 216174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 216274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 216374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 216474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 216574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 216674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 216774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 216874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 216974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 217074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 217174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 217274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 217574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 217674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 217774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 217874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 217974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 218074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 218274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 218374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 218474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 218574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 218774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 218874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 21891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 21901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2192bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2193bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 21941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 21951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 21961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 21971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 21981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 21991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 22011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 22031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 22041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 22051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 22061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 22071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 22081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 220974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2211bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2212bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 22131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 22141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 22151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 221674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2217bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2218bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 22191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2220bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2221bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2222bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 22231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 22241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 22261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 22271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 22291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 22301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 22321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 22331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 22341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2236bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 22371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 22391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 22411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2243bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 22441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 22451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 22461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 22471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 22491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 22501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 22521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2256b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2257b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2258b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2259b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 22607303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2261b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 226296f0819f81293076e652792794a961543e6750d7Mathias Agopian 2263b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226896f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 226996f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 227096f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 227196f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 227296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 227396f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 227496f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 227596f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2278076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 227996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2282076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 228396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = android_atomic_inc(&mNameGenerator); 228696f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 228796f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 229196f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 229296f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 229396f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 229496f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 229596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 229696f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 229796f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 229896f0819f81293076e652792794a961543e6750d7Mathias Agopian } 229996f0819f81293076e652792794a961543e6750d7Mathias Agopian } 230096f0819f81293076e652792794a961543e6750d7Mathias Agopian} 2301076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const { 2302076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 230396f0819f81293076e652792794a961543e6750d7Mathias Agopian const wp<LayerBaseClient>& layer(mLayers.valueFor(i)); 230496f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 230596f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 230696f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2307076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2308076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 231196f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const { 2312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const { 2315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return -1; 2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 231796f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 2318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 232396f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->createSurface(this, pid, name, params, 232496f0819f81293076e652792794a961543e6750d7Mathias Agopian display, w, h, format, flags); 2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 232696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 232796f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->removeSurface(this, sid); 2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 232996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) { 233096f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->setClientState(this, count, states); 2331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2334b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2335b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger) 2336b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : ctrlblk(0), mBitmap(0), mFlinger(flinger) 2337b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int pgsize = getpagesize(); 2339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); 2340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mCblkHeap = new MemoryHeapBase(cblksize, 0, 2342b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian "SurfaceFlinger Client control-block"); 2343b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2344b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); 2345b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { // construct the shared structure in-place. 2346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian new(ctrlblk) SharedClient; 2347b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2349b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2350b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient() 2351b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2352b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { 2353b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk->~SharedClient(); // destroy our shared-structure. 2354b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2355b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2356b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2357b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * When a UserClient dies, it's unclear what to do exactly. 2358b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * We could go ahead and destroy all surfaces linked to that client 2359b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * however, it wouldn't be fair to the main Client 2360b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * (usually the the window-manager), which might want to re-target 2361b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * the layer to another UserClient. 2362b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * I think the best is to do nothing, or not much; in most cases the 2363b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * WM itself will go ahead and clean things up when it detects a client of 2364b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * his has died. 2365b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * The remaining question is what to display? currently we keep 2366b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * just keep the current buffer. 2367b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2368b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2369b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2370b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const { 2371b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return ctrlblk == 0 ? NO_INIT : NO_ERROR; 2372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2373b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2374b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer) 2375b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2376b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = layer->getToken(); 2377b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (name >= 0) { 2378579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian int32_t mask = 1LU<<name; 2379579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { 2380579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); 2381579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2382b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2383b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2384b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2385b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const { 2386b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mCblkHeap; 2387b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2388b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const 2390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = NAME_NOT_FOUND; 2392b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> layer(mFlinger->getLayer(sur)); 239389c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis if (layer == 0) { 239489c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis return name; 239589c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis } 2396b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2397579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // if this layer already has a token, just return it 2398b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = layer->getToken(); 239989c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis if ((name >= 0) && (layer->getClient() == this)) { 2400579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return name; 240189c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis } 2402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = 0; 2404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian do { 2405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t mask = 1LU<<name; 2406b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { 2407b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // we found and locked that name 2408579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian status_t err = layer->setToken( 2409579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const_cast<UserClient*>(this), ctrlblk, name); 2410579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (err != NO_ERROR) { 2411579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // free the name 2412579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian android_atomic_and(~mask, &mBitmap); 2413579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian name = err; 2414579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2415b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian break; 2416b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2417b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (++name > 31) 2418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = NO_MEMORY; 2419b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } while(name >= 0); 2420b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 242153503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)", 242253503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian // sur->asBinder().get(), name, this, mBitmap); 2423b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return name; 2424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2425b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2426b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface( 2427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2428b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2429b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian uint32_t flags) { 2431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2432b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2433b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) { 2434b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) { 2437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2439b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2440b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 24562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 24602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 24612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 24622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 24642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 24652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 24662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 24682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 24692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 24702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 24712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 24722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 24732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 24742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 24752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 24762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 24772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 24782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 24792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 24802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 24812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 24822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 24842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 24852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 24862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 24872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 24882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 24892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 24902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 24912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 24922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 24932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 24942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 24952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2500eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2501eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2504eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2505eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2507eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2510eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2513eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2518eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 25262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 25282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 25292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 25302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 25312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 25322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2534eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2535eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2536eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2537eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2538eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2540eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 25410d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 25422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 255059119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 255159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 255259119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 255359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2560076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2565