SurfaceFlinger.cpp revision c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33
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 1479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 1499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 1519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 152b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return plane; 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<GraphicPlane&>( 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 1708b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1713330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 172a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.stop", "bootanim"); 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef() 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Wait for the main thread to be done with its initialization 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.wait(); 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (r<<11)|(g<<5)|b; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI( "SurfaceFlinger's main thread ready to run. " 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Initializing graphics H/W..."); 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we only support one display currently 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int dpy = 0; 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the main display 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayHardware* const hw = new DisplayHardware(this, dpy); 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setDisplayHardware(hw); 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian // create the shared control-block 2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerHeap = new MemoryHeapBase(4096, 2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 2068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 2098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2107303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian new(mServerCblk) surface_flinger_cblk_t; 2117303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize primary screen 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (other display should be initialized in the same manner, but 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asynchronously, as they could come and go. None of this is supported 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // yet). 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(dpy)); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = plane.displayHardware(); 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t w = hw.getWidth(); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t h = hw.getHeight(); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t f = hw.getFormat(); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.makeCurrent(); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the shared control block 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mServerCblk->connected |= 1<<dpy; 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project display_cblk_t* dcblk = mServerCblk->displays + dpy; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(dcblk, 0, sizeof(display_cblk_t)); 2272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 2282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->format = f; 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = ISurfaceComposer::eOrientationDefault; 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->xdpi = hw.getDpiX(); 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->ydpi = hw.getDpiY(); 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->fps = hw.getRefreshRate(); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->density = hw.getDensity(); 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Initialize OpenGL|ES 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber glPixelStorei(GL_PACK_ALIGNMENT, 4); 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_VERTEX_ARRAY); 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glShadeModel(GL_FLAT); 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_CULL_FACE); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t g1 = pack565(0x17,0x2f,0x17); 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint16_t textureData[4] = { g0, g1, g1, g0 }; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &mWormholeTexName); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glViewport(0, 0, w, h); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_PROJECTION); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glOrthof(0, w, h, 0, 0, 1); 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerDim::initDimmer(this, w, h); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mReadyToRunBarrier.open(); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * We're now ready to accept clients... 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 271a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian property_set("ctl.start", "bootanim"); 2728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent() 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian while (true) { 285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t timeout = -1; 2860408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t freezeDisplayTimeout = ms2ns(5000); 287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (UNLIKELY(isFrozen())) { 288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // wait 5 seconds 289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const nsecs_t now = systemTime(); 290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian if (mFreezeDisplayTime == 0) { 291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mFreezeDisplayTime = now; 292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian timeout = waitTime>0 ? waitTime : 0; 295bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project } 296f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 297bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // see if we timed out 3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (isFrozen()) { 3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian const nsecs_t now = systemTime(); 3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian nsecs_t frozenTime = (now - mFreezeDisplayTime); 3030408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (frozenTime >= freezeDisplayTimeout) { 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we timed out and are still frozen 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay, mFreezeCount); 3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = 0; 309bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project mFreezeDisplay = false; 3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian } 3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian 3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian if (msg != 0) { 3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian switch (msg->what) { 3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian case MessageQueue::INVALIDATE: 3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian // invalidate message, just return to the main loop 3170408772e34931351d062f2088b611325ddaa6cdbMathias Agopian return; 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() { 324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian mEventQueue.invalidate(); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const { 328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // this is the IPC call 329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian const_cast<SurfaceFlinger*>(this)->signalEvent(); 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return mEventQueue.postMessage(msg, reltime, flags); 336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian nsecs_t reltime, uint32_t flags) 340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{ 341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime, flags); 342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (res == NO_ERROR) { 343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian msg->wait(); 344bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 345bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return res; 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark - 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop() 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project waitForEvent(); 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // check for transactions 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mConsoleSignals)) { 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleConsoleEvents(); 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(mTransactionCount == 0)) { 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if we're in a global transaction, don't do anything. 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t transactionFlags = getTransactionFlags(mask); 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(transactionFlags)) { 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleTransaction(transactionFlags); 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // post surfaces (if needed) 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handlePageFlip(); 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 375a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (UNLIKELY(mHwWorkListDirty)) { 376a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // build the h/w work list 377a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian handleWorkList(); 378a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 379a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 3818a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian if (LIKELY(hw.canDraw() && !isFrozen())) { 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // repaint the framebuffer (if needed) 38335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 38435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = hw.getCurrentBufferIndex(); 38535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog& logger(GraphicLog::getInstance()); 38635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 38735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT, index); 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project handleRepaint(); 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian // inform the h/w that we're done compositing 39135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 39274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian hw.compositionComplete(); 39374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 39435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 3958392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala postFramebuffer(); 3968392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala 397c479e18db0216f7096fefe85ffa71ab00329aef3Mathias Agopian logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockClients(); 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian logger.log(GraphicLog::SF_REPAINT_DONE, index); 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pretend we did the post 403e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockClients(); 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project usleep(16667); // 60 fps period 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!mInvalidRegion.isEmpty()) { 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 4149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 4159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = now; 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.flip(mInvalidRegion); 4179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime = systemTime() - now; 4189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers = 0; 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidRegion.clear(); 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents() 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something to do with the console 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int what = android_atomic_and(0, &mConsoleSignals); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleAcquired) { 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.acquireScreen(); 4319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // this is a temporary work-around, eventually this should be called 4329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager 433abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43659119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (mDeferReleaseConsole && hw.isScreenAcquired()) { 43762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // We got the release signal before the acquire signal 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = false; 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eConsoleReleased) { 44359119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (hw.isScreenAcquired()) { 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.releaseScreen(); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDeferReleaseConsole = true; 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian Vector< sp<LayerBase> > ditchedLayers; 4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 4574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 4584da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * Perform and commit the transaction 4594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 4604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 4613d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian { // scope for the lock 4623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian Mutex::Autolock _l(mStateLock); 4639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 4649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction = now; 4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian handleTransactionLocked(transactionFlags, ditchedLayers); 4669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime = systemTime() - now; 4679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction = 0; 468ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian // here the transaction has been committed 4703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 4724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 4734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * Clean-up all layers that went away 4744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * (do this without the lock held) 4754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 476a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 4773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = ditchedLayers.size(); 4783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 4790852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian if (ditchedLayers[i] != 0) { 4800852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian //LOGD("ditching layer %p", ditchedLayers[i].get()); 4810852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian ditchedLayers[i]->ditch(); 4820852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian } 4833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian } 4843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked( 4873d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers) 4883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 4893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layersNeedTransaction) { 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Perform our own transaction if needed 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (transactionFlags & eTransactionNeeded) { 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != mDrawingState.orientation) { 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the orientation has changed, recompute all visible regions 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and invalidate everything. 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int dpy = 0; 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int orientation = mCurrentState.orientation; 521c08731e756868653d09d3e49b723706df3687070Mathias Agopian const uint32_t type = mCurrentState.orientationType; 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GraphicPlane& plane(graphicPlane(dpy)); 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project plane.setOrientation(orientation); 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // update the shared control block 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(plane.displayHardware()); 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dcblk->orientation = orientation; 5292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->w = plane.getWidth(); 5302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian dcblk->h = plane.getHeight(); 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freezing or unfreezing the display -> trigger animation if needed 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay = mCurrentState.freezeDisplay; 539064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian if (mFreezeDisplay) 540064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian mFreezeDisplayTime = 0; 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // layers have been added 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // some layers might have been removed, so 5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // we need to update the regions they're exposing. 5500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (mLayersRemoved) { 55148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mLayersRemoved = false; 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 5543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const size_t count = previousLayers.size(); 5553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian for (size_t i=0 ; i<count ; i++) { 5560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian const sp<LayerBase>& layer(previousLayers[i]); 5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian if (currentLayers.indexOf( layer ) < 0) { 5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian // this layer is not visible anymore 5593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian ditchedLayers.add(layer); 5605d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 5610aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 5620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 579ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const DisplayHardware& hw(plane.displayHardware()); 580ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region screenRegion(hw.bounds()); 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool secureFrameBuffer = false; 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = currentLayers[i]; 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->validateVisibility(planeTransform); 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 594970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Layer::State& s(layer->drawingState()); 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 617970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool translucent = layer->needsBlending(); 619970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian const Rect bounds(layer->visibleBounds()); 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.andSelf(screenRegion); 622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian visibleRegion.subtractSelf(layer->transparentRegionScreen); 626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const int32_t layerOrientation = layer->getOrientation(); 630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.orSelf(layer->visibleRegionScreen); 653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 655a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 666a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldVisibleRegion = layer->visibleRegionScreen; 669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldCoveredRegion = layer->coveredRegionScreen; 670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.orSelf(dirty); 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 6808b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Store the visible region is screen space 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 685970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // If a secure layer is partially visible, lock-down the screen! 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->isSecure() && !visibleRegion.isEmpty()) { 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project secureFrameBuffer = true; 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 691970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian // invalidate the areas where a layer was removed 692970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 693970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian mDirtyRegionRemovedLayer.clear(); 694970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecureFrameBuffer = secureFrameBuffer; 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project opaqueRegion = aboveOpaqueLayers; 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction() 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = false; 704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mTransactionCV.broadcast(); 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip() 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool visibleRegions = mVisibleRegionsDirty; 710a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian LayerVector& currentLayers( 711a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const_cast<LayerVector&>(mDrawingState.layersSortedByZ)); 712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegions |= lockPageFlip(currentLayers); 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw = graphicPlane(0).displayHardware(); 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region screenRegion(hw.bounds()); 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (visibleRegions) { 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian /* 7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian * rebuild the visible layer list 7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian */ 7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.clear(); 7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 7254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian size_t count = currentLayers.size(); 7264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.setCapacity(count); 7274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian for (size_t i=0 ; i<count ; i++) { 7284da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 7294da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian mVisibleLayersSortedByZ.add(currentLayers[i]); 7304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian } 7314da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion = screenRegion.subtract(opaqueRegion); 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = false; 734ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockPageFlip(currentLayers); 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.andSelf(screenRegion); 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 741ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 742ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 743ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 744ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 745ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool recomputeVisibleRegions = false; 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->lockPageFlip(recomputeVisibleRegions); 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return recomputeVisibleRegions; 756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GraphicPlane& plane(graphicPlane(0)); 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform(plane.transform()); 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t count = currentLayers.size(); 763076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* layers = currentLayers.array(); 764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 765b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const sp<LayerBase>& layer(layers[i]); 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->unlockPageFlip(planeTransform, mDirtyRegion); 767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 770a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList() 771a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 772a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty = false; 773a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 774a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (hwc.initCheck() == NO_ERROR) { 775a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const size_t count = currentLayers.size(); 777a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian hwc.createWorkList(count); 77845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 77945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; cur && i<count ; i++) { 78045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian currentLayers[i]->setGeometry(&cur[i]); 78173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian if (mDebugDisableHWC) { 78273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].compositionType = HWC_FRAMEBUFFER; 78373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian cur[i].flags |= HWC_SKIP_LAYER; 78473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian } 785a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 786a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 787a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint() 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 791b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 792b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.orSelf(mDirtyRegion); 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mDebugRegion)) { 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project debugFlashRegions(); 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 798b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // set the frame buffer 799b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 800b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glMatrixMode(GL_MODELVIEW); 801b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian glLoadIdentity(); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = hw.getFlags(); 8048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if ((flags & DisplayHardware::SWAP_RECTANGLE) || 8058b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber (flags & DisplayHardware::BUFFER_PRESERVED)) 806df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian { 80729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 80929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 81029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian if (flags & DisplayHardware::SWAP_RECTANGLE) { 811b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we really should be able to pass a region to 81229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // SWAP_RECTANGLE so that we don't have to redraw all this. 81329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian mDirtyRegion.set(mInvalidRegion.bounds()); 81429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } else { 81529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // in the BUFFER_PRESERVED case, obviously, we can update only 81629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // what's needed and nothing more. 81729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // NOTE: this is NOT a common case, as preserving the backbuffer 81829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // is costly and usually involves copying the whole update back. 81929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian } 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 82195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (flags & DisplayHardware::PARTIAL_UPDATES) { 82229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 823df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 82495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 82529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle instead of a region (see DisplayHardware::flip()) 826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(mInvalidRegion.bounds()); 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 82829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidRegion = mDirtyRegion; 831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compose all surfaces 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project composeSurfaces(mDirtyRegion); 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // clear the dirty regions 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.clear(); 839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty) 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(!mWormholeRegion.isEmpty())) { 844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // should never happen unless the window manager has a bug 845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // draw something... 846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawWormhole(); 847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 848a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 849a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian status_t err = NO_ERROR; 8504da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 85145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian size_t count = layers.size(); 852a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 853a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 854a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian HWComposer& hwc(hw.getHwComposer()); 85545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc_layer_t* const cur(hwc.getLayers()); 856a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 85745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian LOGE_IF(cur && hwc.getNumLayers() != count, 85845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 85945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian hwc.getNumLayers(), count); 860a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // just to be extra-safe, use the smallest count 86224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling if (hwc.initCheck() == NO_ERROR) { 86324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 86424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling } 865a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * update the per-frame h/w composer data for each layer 86845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and build the transparent region of the FB 86945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 87045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian Region transparent; 87145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur) { 87245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 87345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 87445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->setPerFrameData(&cur[i]); 87545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur[i].hints & HWC_HINT_CLEAR_FB) { 87645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!(layer->needsBlending())) { 87745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian transparent.orSelf(layer->visibleRegionScreen); 87845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 88145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian err = hwc.prepare(); 88245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 884a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 88545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 88645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * clear the area of the FB that need to be transparent 88745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 888a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian transparent.andSelf(dirty); 889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (!transparent.isEmpty()) { 890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glClearColor(0,0,0,0); 891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian Region::const_iterator it = transparent.begin(); 892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian Region::const_iterator const end = transparent.end(); 893a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const int32_t height = hw.getHeight(); 894a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian while (it != end) { 895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const Rect& r(*it++); 896a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const GLint sy = height - (r.top + r.height()); 897a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glScissor(r.left, sy, r.width(), r.height()); 898a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 900a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian 90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian /* 90445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian * and then, render the layers targeted at the framebuffer 90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian */ 90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (cur) { 908586a0deb76012c4347298c11df460631853b67f8Antti Hatala if ((cur[i].compositionType != HWC_FRAMEBUFFER) && 909586a0deb76012c4347298c11df460631853b67f8Antti Hatala !(cur[i].flags & HWC_SKIP_LAYER)) { 91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian // skip layers handled by the HAL 91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian continue; 91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 91473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 91545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const sp<LayerBase>& layer(layers[i]); 91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian const Region clip(dirty.intersect(layer->visibleRegionScreen)); 91745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian if (!clip.isEmpty()) { 91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian layer->draw(clip); 91945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 92045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian } 921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients() 924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); 926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = drawingLayers.size(); 927076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBase> const* const layers = drawingLayers.array(); 928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; ++i) { 929076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBase>& layer = layers[i]; 930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->finishPageFlip(); 931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions() 935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 9370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const uint32_t flags = hw.getFlags(); 9380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 9390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 9400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian (flags & DisplayHardware::BUFFER_PRESERVED))) { 9410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 9420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian mDirtyRegion.bounds() : hw.bounds()); 9430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian composeSurfaces(repaint); 9440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian } 9450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 9460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian TextureManager::deactivateTextures(); 947df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian 948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_SCISSOR_TEST); 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian static int toggle = 0; 9530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian toggle = 1 - toggle; 9540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (toggle) { 9550a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 0, 1, 1); 9560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 9570a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glColor4f(1, 1, 0, 1); 9580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 96020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = mDirtyRegion.begin(); 96120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = mDirtyRegion.end(); 96220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 96320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLfloat vertices[][2] = { 965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.top }, 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.left, r.bottom }, 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.bottom }, 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { r.right, r.top } 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_FLOAT, 0, vertices); 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 9730a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian 974b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian if (mInvalidRegion.isEmpty()) { 975b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mDirtyRegion.dump("mDirtyRegion"); 976b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian mInvalidRegion.dump("mInvalidRegion"); 977b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian } 978b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian hw.flip(mInvalidRegion); 979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mDebugRegion > 1) 9810a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian usleep(mDebugRegion * 1000); 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //mDirtyRegion.dump("mDirtyRegion"); 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Region region(mWormholeRegion.intersect(mDirtyRegion)); 990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (region.isEmpty()) 991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t width = hw.getWidth(); 995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t height = hw.getHeight(); 996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!mDebugBackground)) { 10010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian glClearColor(0,0,0,0); 100220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 100320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 100420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 100520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glClear(GL_COLOR_BUFFER_BIT); 1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { width, height }, { 0, height } }; 1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnableClientState(GL_TEXTURE_COORD_ARRAY); 10177f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external) 10181f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian if (GLExtensions::getInstance().haveTextureExternal()) { 10191f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 10201f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian } 10210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif 1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glMatrixMode(GL_TEXTURE); 1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glLoadIdentity(); 1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 102820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = region.begin(); 102920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = region.end(); 103020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 103120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = height - (r.top + r.height()); 1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1037ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glLoadIdentity(); 1038ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian glMatrixMode(GL_MODELVIEW); 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mFrameCount; 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static int mLastFrameCount = 0; 1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static nsecs_t mLastFpsTime = 0; 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static float mFps = 0; 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameCount++; 1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t now = systemTime(); 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t diff = now - mLastFpsTime; 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (diff > ms2ns(250)) { 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFpsTime = now; 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLastFrameCount = mFrameCount; 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: mFPS has the value we want 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1059076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project addLayer_l(layer); 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1067076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1069f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t i = mCurrentState.layersSortedByZ.add(layer); 10701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (i < 0) ? status_t(i) : status_t(NO_ERROR); 10711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian} 10721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 107396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 107496f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<LayerBaseClient>& lbc) 10751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 107696f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 107796f0819f81293076e652792794a961543e6750d7Mathias Agopian 107896f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 107996f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t name = client->attachLayer(lbc); 108096f0819f81293076e652792794a961543e6750d7Mathias Agopian 108196f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 108296f0819f81293076e652792794a961543e6750d7Mathias Agopian addLayer_l(lbc); 108396f0819f81293076e652792794a961543e6750d7Mathias Agopian 108496f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 108596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 108696f0819f81293076e652792794a961543e6750d7Mathias Agopian 108796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 108896f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 108996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 109096f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = purgatorizeLayer_l(layer); 109196f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) 109296f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 109396f0819f81293076e652792794a961543e6750d7Mathias Agopian return err; 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1096076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1098b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1099b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (lbc != 0) { 1100b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.removeItem( lbc->getSurface()->asBinder() ); 1101b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 1104076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 11073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 11119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 111276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // First add the layer to the purgatory list, which makes sure it won't 111376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // go away, then remove it from the main list (through a transaction). 11149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian ssize_t err = removeLayer_l(layerBase); 111576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err >= 0) { 111676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian mLayerPurgatory.add(layerBase); 111776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 11188c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian 11190b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian layerBase->onRemoved(); 11200b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 11213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // it's possible that we don't find a layer, because it might 11223d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian // have been destroyed already -- this is not technically an error 112396f0819f81293076e652792794a961543e6750d7Mathias Agopian // from the user because there is a race between Client::destroySurface(), 112496f0819f81293076e652792794a961543e6750d7Mathias Agopian // ~Client() and ~ISurface(). 11259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 11269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 11279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 112896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 113096f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->forceVisibilityTransaction(); 113196f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTraversalNeeded); 113296f0819f81293076e652792794a961543e6750d7Mathias Agopian return NO_ERROR; 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1140bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 1144bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian signalEvent(); 1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction() 1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&mTransactionCount); 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction() 1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (android_atomic_dec(&mTransactionCount) == 1) { 1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1158cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 11598b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber // if there is a transaction with a resize, wait for it to 1160cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // take effect before returning. 1161cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mStateLock); 1162cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian while (mResizeTransationPending) { 1163448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1164448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1165448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // just in case something goes wrong in SF, return to the 1166448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian // called after a few seconds. 1167448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1168448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian mResizeTransationPending = false; 1169448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian break; 1170448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian } 1171cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 1; 1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 118562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.freezeDisplay = 0; 1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // flags is intended to communicate some sort of animation behavior 119962b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian // (for instance fading) 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy, 1204c08731e756868653d09d3e49b723706df3687070Mathias Agopian int orientation, uint32_t flags) 1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.orientation != orientation) { 1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1212c08731e756868653d09d3e49b723706df3687070Mathias Agopian mCurrentState.orientationType = flags; 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation = orientation; 1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(eTransactionNeeded); 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionCV.wait(mStateLock); 1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project orientation = BAD_VALUE; 1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return orientation; 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 122396f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, 12247e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian const String8& name, ISurfaceComposerClient::surface_data_t* params, 1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1228076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> layer; 1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<LayerBaseClient::Surface> surfaceHandle; 12306e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian 12316e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 12326e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 12336e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 12346e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian return surfaceHandle; 12356e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 12368b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1238b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> normalLayer; 1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (flags & eFXSurfaceMask) { 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceNormal: 1241a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian normalLayer = createNormalSurface(client, d, w, h, flags, format); 1242a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian layer = normalLayer; 1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceBlur: 12451293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // for now we treat Blur as Dim, until we can implement it 12461293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian // efficiently. 1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case eFXSurfaceDim: 124896f0819f81293076e652792794a961543e6750d7Mathias Agopian layer = createDimSurface(client, d, w, h, flags); 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 125396f0819f81293076e652792794a961543e6750d7Mathias Agopian layer->initStates(w, h, flags); 1254285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian layer->setName(name); 125596f0819f81293076e652792794a961543e6750d7Mathias Agopian ssize_t token = addClientLayer(client, layer); 1256b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project surfaceHandle = layer->getSurface(); 12588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber if (surfaceHandle != 0) { 125996f0819f81293076e652792794a961543e6750d7Mathias Agopian params->token = token; 12601c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->identity = surfaceHandle->getIdentity(); 12611c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->width = w; 12621c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->height = h; 12631c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian params->format = format; 1264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (normalLayer != 0) { 1265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 1266b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mLayerMap.add(surfaceHandle->asBinder(), normalLayer); 1267b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 12681c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian } 1269b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 127096f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return surfaceHandle; 1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1276b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface( 1277f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 127896f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags, 12791c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian PixelFormat& format) 1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (format) { // TODO: take h/w into account 1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1288a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1289a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1290a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 12918f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1292a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1296a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1297a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1298a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1299a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1300a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 130196f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Layer> layer = new Layer(this, display, client); 1302f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian status_t err = layer->setBuffers(w, h, format, flags); 130396f0819f81293076e652792794a961543e6750d7Mathias Agopian if (LIKELY(err != NO_ERROR)) { 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1305076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer.clear(); 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface( 1311f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, DisplayID display, 131296f0819f81293076e652792794a961543e6750d7Mathias Agopian uint32_t w, uint32_t h, uint32_t flags) 1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 131496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerDim> layer = new LayerDim(this, display, client); 1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->initStates(w, h, flags); 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return layer; 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 131996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 13209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 13229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * called by the window manager, when a surface should be marked for 13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * destruction. 13248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * 13250aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * The surface is removed from the current and drawing lists, but placed 13260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * in the purgatory queue, so it's not destroyed right-away (we need 13270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian * to wait for all client's references to go away first). 13289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 13299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 133048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian status_t err = NAME_NOT_FOUND; 13310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian Mutex::Autolock _l(mStateLock); 133296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer = client->getLayerUser(sid); 133348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (layer != 0) { 133448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian err = purgatorizeLayer_l(layer); 133548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (err == NO_ERROR) { 133648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian setTransactionFlags(eTransactionNeeded); 133748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 13389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 13399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 13409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 13419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 13429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer) 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1344759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian // called by ~ISurface() when all references are gone 13458b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1346f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian class MessageDestroySurface : public MessageBase { 13470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger; 1348f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian sp<LayerBaseClient> layer; 1349f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian public: 13500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian MessageDestroySurface( 13510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer) 13520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian : flinger(flinger), layer(layer) { } 1353f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian virtual bool handler() { 1354cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian sp<LayerBaseClient> l(layer); 1355cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian layer.clear(); // clear it outside of the lock; 1356f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 1357759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian /* 13588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * remove the layer from the current list -- chances are that it's 13598b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * not in the list anyway, because it should have been removed 13608b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber * already upon request of the client (eg: window manager). 1361759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * However, a buggy client could have not done that. 1362759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * Since we know we don't have any more clients, we don't need 1363759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian * to use the purgatory. 1364759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian */ 1365cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian status_t err = flinger->removeLayer_l(l); 136676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian if (err == NAME_NOT_FOUND) { 136776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // The surface wasn't in the current list, which means it was 136876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // removed already, which means it is in the purgatory, 136976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // and need to be removed from there. 137076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // This needs to happen from the main thread since its dtor 137176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // must run from there (b/c of OpenGL ES). Additionally, we 137276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // can't really acquire our internal lock from 137376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // destroySurface() -- see postMessage() below. 137476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian ssize_t idx = flinger->mLayerPurgatory.remove(l); 137576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian LOGE_IF(idx < 0, 137676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian "layer=%p is not in the purgatory list", l.get()); 137776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian } 137876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian 13798c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian LOGE_IF(err<0 && err != NAME_NOT_FOUND, 13808c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 1381f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian return true; 1382f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian } 1383f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian }; 13843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian 1385bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian postMessageAsync( new MessageDestroySurface(this, layer) ); 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState( 139096f0819f81293076e652792794a961543e6750d7Mathias Agopian const sp<Client>& client, 1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t count, 1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const layer_state_t* states) 1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = 0; 1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<count ; i++) { 139796f0819f81293076e652792794a961543e6750d7Mathias Agopian const layer_state_t& s(states[i]); 139896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1399076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (layer != 0) { 1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t what = s.what; 1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & ePositionChanged) { 1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setPosition(s.x, s.y)) 1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eLayerChanged) { 1406f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setLayer(s.z)) { 1408f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1409f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian mCurrentState.layersSortedByZ.add(layer); 1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need traversal (state changed) 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // AND transaction (list changed) 1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTransactionNeeded|eTraversalNeeded; 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eSizeChanged) { 1416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (layer->setSize(s.w, s.h)) { 1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mResizeTransationPending = true; 1419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eAlphaChanged) { 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eMatrixChanged) { 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setMatrix(s.matrix)) 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eTransparentRegionChanged) { 1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setTransparentRegionHint(s.transparentRegion)) 1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (what & eVisibilityChanged) { 1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->setFlags(s.flags, s.mask)) 1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eTraversalNeeded; 1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags) { 1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTransactionFlags(flags); 1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy) 1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleReleased, &mConsoleSignals); 1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy) 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this may be called by a signal handler, we can't do too much in here 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14611d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 1464375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (!mDump.checkCalling()) { 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, "Permission Denial: " 1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingPid(), 1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->getCallingUid()); 1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 14719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 14729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // figure out if we're stuck somewhere 14739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t now = systemTime(); 14749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 14759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 14769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 14779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 14789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 14799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 14809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 14819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 14829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 14839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 14849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 14859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 14879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 14888b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber snprintf(buffer, SIZE, 14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 14971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const sp<LayerBase>& layer(currentLayers[i]); 14981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian layer->dump(result, buffer, SIZE); 14991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian const Layer::State& s(layer->drawingState()); 1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.transparentRegion.dump(result, "transparentRegion"); 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mWormholeRegion.dump(result, "WormholeRegion"); 1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, 1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeDisplay?"yes":"no", mFreezeCount, 1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.orientation, hw.canDraw()); 1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result.append(buffer); 15129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, 15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last eglSwapBuffers() time: %f us\n" 15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian " last transaction time : %f us\n", 15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); 15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inSwapBuffersDuration || !locked) { 15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inSwapBuffersDuration/1000.0); 15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 15249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (inTransactionDuration || !locked) { 15259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian snprintf(buffer, SIZE, " transaction time: %f us\n", 15269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian inTransactionDuration/1000.0); 15279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian result.append(buffer); 15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 15291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 153073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian HWComposer& hwc(hw.getHwComposer()); 153173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian snprintf(buffer, SIZE, " h/w composer %s and %s\n", 153273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 153373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC ? "disabled" : "enabled"); 153473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian result.append(buffer); 15358372785879d329f592f6883620b5a32d80d74691Mathias Agopian hwc.dump(result, buffer, SIZE); 153673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 15373330b203039dea366d4981db1408a460134b2d2cMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian alloc.dump(result); 15391d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling hw.dump(result); 15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (locked) { 15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mStateLock.unlock(); 15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project write(fd, result.string(), result.size()); 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case OPEN_GLOBAL_TRANSACTION: 1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CLOSE_GLOBAL_TRANSACTION: 1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case SET_ORIENTATION: 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case FREEZE_DISPLAY: 1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case UNFREEZE_DISPLAY: 1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 156059119e658a12279e8fff508f8773843de2d90917Mathias Agopian case TURN_ELECTRON_BEAM_OFF: 15619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian case TURN_ELECTRON_BEAM_ON: 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 1566a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 1567375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { 1568375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1569375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1570375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 15731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 15741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 15751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 15761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 15771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 15781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 15791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 15801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) { 15811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian LOGE("Permission Denial: " 15821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 15831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 15841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 15851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 15881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1591b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 1592375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (UNLIKELY(!mHardwareTest.checkCalling())) { 1593375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 1594375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 1595375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 1596375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 1597375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 160201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 160335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1003: // SHOW_BACKGROUND 1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugBackground = n ? 1 : 0; 1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 161373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian case 1008: // toggle use of hw composer 161473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian n = data.readInt32(); 161573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC = n ? 1 : 0; 1616ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian invalidateHwcGeometry(); 161773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian // fall-through... 1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe 1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signalEvent(); 1623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1624cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1625cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 1626cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1627cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 162935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1006:{ // enable/disable GraphicLog 163035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int enabled = data.readInt32(); 163135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian GraphicLog::getInstance().setEnabled(enabled); 163235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return NO_ERROR; 163335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian } 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1007: // set mFreezeCount 1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeCount = data.readInt32(); 16360408772e34931351d062f2088b611325ddaa6cdbMathias Agopian mFreezeDisplayTime = 0; 1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 163901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugBackground); 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(hw.getPageFlipCount()); 1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165559119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 165659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 16589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 165959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 166059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 166159119e658a12279e8fff508f8773843de2d90917Mathias Agopian return INVALID_OPERATION; 166259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 166359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // get screen geometry 166459119e658a12279e8fff508f8773843de2d90917Mathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 166559119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_w = hw.getWidth(); 166659119e658a12279e8fff508f8773843de2d90917Mathias Agopian const uint32_t hw_h = hw.getHeight(); 166759119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat u = 1; 166859119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLfloat v = 1; 166959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 167059119e658a12279e8fff508f8773843de2d90917Mathias Agopian // make sure to clear all GL error flags 167159119e658a12279e8fff508f8773843de2d90917Mathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 167259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 167359119e658a12279e8fff508f8773843de2d90917Mathias Agopian // create a FBO 167459119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLuint name, tname; 167559119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenTextures(1, &tname); 167659119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 16779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 167959119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (glGetError() != GL_NO_ERROR) { 1680015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 168159119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint tw = (2 << (31 - clz(hw_w))); 168259119e658a12279e8fff508f8773843de2d90917Mathias Agopian GLint th = (2 << (31 - clz(hw_h))); 16839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 168559119e658a12279e8fff508f8773843de2d90917Mathias Agopian u = GLfloat(hw_w) / tw; 168659119e658a12279e8fff508f8773843de2d90917Mathias Agopian v = GLfloat(hw_h) / th; 168759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 168859119e658a12279e8fff508f8773843de2d90917Mathias Agopian glGenFramebuffersOES(1, &name); 168959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 16919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 169259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 16939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // redraw the screen entirely... 16949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClearColor(0,0,0,1); 16959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const size_t count = layers.size(); 16989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const sp<LayerBase>& layer(layers[i]); 17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian layer->drawForSreenShot(); 17019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 170259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 17059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteFramebuffersOES(1, &name); 170759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *textureName = tname; 17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *uOut = u; 17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian *vOut = v; 17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 171359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 171559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 171959119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 17219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 172259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 172859119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 17309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 17319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 17329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 173559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 17419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 17539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 17569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 178359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // the full animation is 24 frames 17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const int nbFrames = 12; 17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 181559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the white highlight (we use the last vertices) 183259119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDisable(GL_TEXTURE_2D); 183359119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(vg, vg, vg, 1); 18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=0 ; i<nbFrames ; i++) { 18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDeleteTextures(1, &tname); 18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result = PERMISSION_DENIED; 18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return INVALID_OPERATION; 18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // get screen geometry 18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const DisplayHardware& hw(graphicPlane(0).displayHardware()); 18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_w = hw.getWidth(); 18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const uint32_t hw_h = hw.getHeight(); 18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const Region screenBounds(hw.bounds()); 18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat u, v; 18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLuint tname; 18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian result = renderScreenToTextureLocked(0, &tname, &u, &v); 18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (result != NO_ERROR) { 18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // back to main framebuffer 18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_SCISSOR_TEST); 18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian GLfloat vtx[8]; 18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBindTexture(GL_TEXTURE_2D, tname); 18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glVertexPointer(2, GL_FLOAT, 0, vtx); 18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class s_curve_interpolator { 18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float nbFrames, s, v; 18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator(int nbFrames, float s) 18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : nbFrames(1.0f / (nbFrames-1)), s(s), 19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v(1.0f + expf(-s + 0.5f*s)) { 19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float operator()(int f) { 19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float x = f * nbFrames; 19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class v_stretch { 19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch(uint32_t hw_w, uint32_t hw_h) 19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 191359119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w + (hw_w * v); 19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = hw_h - (hw_h * v); 19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class h_stretch { 19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat hw_w, hw_h; 19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch(uint32_t hw_w, uint32_t hw_h) 19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian : hw_w(hw_w), hw_h(hw_h) { 19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian void operator()(GLfloat* vtx, float v) { 19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat w = hw_w - (hw_w * v); 19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat h = 1.0f; 19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat x = (hw_w - w) * 0.5f; 19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const GLfloat y = (hw_h - h) * 0.5f; 19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[0] = x; vtx[1] = y; 19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[2] = x; vtx[3] = y + h; 19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[4] = x + w; vtx[5] = y + h; 19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vtx[6] = x + w; vtx[7] = y; 19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1944a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian // the full animation is 12 frames 1945a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian int nbFrames = 8; 19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itr(nbFrames, 7.5f); 19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itg(nbFrames, 8.0f); 19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian s_curve_interpolator itb(nbFrames, 8.5f); 19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian h_stretch hverts(hw_w, hw_h); 19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_BLEND); 19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisable(GL_TEXTURE_2D); 19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float v = itg(i); 19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hverts(vtx, v); 19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColor4f(1-v, 1-v, 1-v, 1); 19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 1963a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian nbFrames = 4; 19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian v_stretch vverts(hw_w, hw_h); 19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_BLEND); 19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glBlendFunc(GL_ONE, GL_ONE); 19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian for (int i=nbFrames-1 ; i>=0 ; i--) { 19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian float x, y, w, h; 19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vr = itr(i); 19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vg = itg(i); 19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian const float vb = itb(i); 197259119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // clear screen 197459119e658a12279e8fff508f8773843de2d90917Mathias Agopian glColorMask(1,1,1,1); 19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_TEXTURE_2D); 19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the red plane 19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vr); 19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,0,0,1); 19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the green plane 19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vg); 19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,1,0,1); 19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // draw the blue plane 19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian vverts(vtx, vb); 19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(0,0,1,1); 19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian hw.flip(screenBounds); 199459119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 199559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glColorMask(1,1,1,1); 19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glEnable(GL_SCISSOR_TEST); 19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 199959119e658a12279e8fff508f8773843de2d90917Mathias Agopian glDeleteTextures(1, &tname); 200059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 20019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 20059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2006abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (!hw.canDraw()) { 20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already off 20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2013abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2014abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOffAnimationImplLocked(); 2015abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2016abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2017abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian // always clear the whole screen at the end of the animation 2018abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClearColor(0,0,0,1); 2019abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glDisable(GL_SCISSOR_TEST); 2020abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2021abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian glEnable(GL_SCISSOR_TEST); 2022abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian hw.flip( Region(hw.bounds()) ); 2023abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian 2024015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(false); 2025015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 202859119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian{ 203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian class MessageTurnElectronBeamOff : public MessageBase { 203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian SurfaceFlinger* flinger; 2032abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t result; 203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian public: 2035abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2036abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 203759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 203859119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t getResult() const { 203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return result; 204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 204159119e658a12279e8fff508f8773843de2d90917Mathias Agopian virtual bool handler() { 204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2043abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOffImplLocked(mode); 204459119e658a12279e8fff508f8773843de2d90917Mathias Agopian return true; 204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian }; 204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2048abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian status_t res = postMessageSync(msg); 205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian if (res == NO_ERROR) { 205159119e658a12279e8fff508f8773843de2d90917Mathias Agopian res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 20529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // work-around: when the power-manager calls us we activate the 20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // animation. eventually, the "on" animation will be called 20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // by the power-manager itself 2056abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian mElectronBeamAnimationMode = mode; 205759119e658a12279e8fff508f8773843de2d90917Mathias Agopian } 205859119e658a12279e8fff508f8773843de2d90917Mathias Agopian return res; 205959119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 206059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2063abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian if (hw.canDraw()) { 20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian // we're already on 20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 2070abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2071abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian electronBeamOnAnimationImplLocked(); 2072abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian } 2073015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian hw.setCanDraw(true); 2074a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2075a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian // make sure to redraw the whole screen when the animation is done 2076a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian mDirtyRegion.set(hw.bounds()); 2077a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian signalEvent(); 2078a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian 2079015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian return NO_ERROR; 20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 20839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{ 20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian class MessageTurnElectronBeamOn : public MessageBase { 20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian SurfaceFlinger* flinger; 2086abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian int32_t mode; 20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t result; 20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian public: 2089abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2090abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian status_t getResult() const { 20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return result; 20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 20959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian virtual bool handler() { 20969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 2097abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian result = flinger->turnElectronBeamOnImplLocked(mode); 20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return true; 20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian }; 21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 2102abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 21039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return NO_ERROR; 21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian} 21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// --------------------------------------------------------------------------- 21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian 210874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 210974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, 211074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* w, uint32_t* h, PixelFormat* f, 2111bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2112bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 211374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 211474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian status_t result = PERMISSION_DENIED; 211574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 211674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // only one display supported for now 211774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 211874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 211974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 212074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 212174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return INVALID_OPERATION; 212274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 212374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // get screen geometry 212474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 212574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_w = hw.getWidth(); 212674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const uint32_t hw_h = hw.getHeight(); 212774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 212874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if ((sw > hw_w) || (sh > hw_h)) 212974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return BAD_VALUE; 213074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 213174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sw = (!sw) ? hw_w : sw; 213274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sh = (!sh) ? hw_h : sh; 213374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t size = sw * sh * 4; 213474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2135c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2136c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian sw, sh, minLayerZ, maxLayerZ); 2137c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 213874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // make sure to clear all GL error flags 213974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian while ( glGetError() != GL_NO_ERROR ) ; 214074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 214174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // create a FBO 214274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLuint name, tname; 214374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenRenderbuffersOES(1, &tname); 214474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 214574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 214674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glGenFramebuffersOES(1, &name); 214774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 214874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 214974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 215074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 215174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2152c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 2153c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: FBO created, status=0x%x", status); 2154c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 215574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 215674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 215774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // invert everything, b/c glReadPixel() below will invert the FB 215874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, sw, sh); 2159f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian glScissor(0, 0, sw, sh); 216074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 216174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPushMatrix(); 216274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glLoadIdentity(); 216374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glOrthof(0, hw_w, 0, hw_h, 0, 1); 216474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 216574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 216674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // redraw the screen entirely... 216774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClearColor(0,0,0,1); 216874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glClear(GL_COLOR_BUFFER_BIT); 2169f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian 2170c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: glClear() issued"); 2171c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 217274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const size_t count = layers.size(); 217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian for (size_t i=0 ; i<count ; ++i) { 217574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian const sp<LayerBase>& layer(layers[i]); 2176bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian const uint32_t z = layer->drawingState().z; 2177bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian if (z >= minLayerZ && z <= maxLayerZ) { 2178bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian layer->drawForSreenShot(); 2179bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian } 218074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2182c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: All layers rendered"); 2183c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 218474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // XXX: this is needed on tegra 218574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glScissor(0, 0, sw, sh); 218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 218774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // check for errors and return screen capture 218874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() != GL_NO_ERROR) { 218974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // error while rendering 219074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = INVALID_OPERATION; 219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // allocate shared memory large enough to hold the 219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // screen capture 219474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<MemoryHeapBase> base( 219574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian new MemoryHeapBase(size, 0, "screen-capture") ); 219674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian void* const ptr = base->getBase(); 219774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (ptr) { 2198c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 2199c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: about to call glReadPixels(0,0,%d,%d,...,%p)", 2200c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian sw, sh, ptr); 2201c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 220274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // capture the screen with glReadPixels() 220374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 220474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian if (glGetError() == GL_NO_ERROR) { 220574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *heap = base; 220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *w = sw; 220774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *h = sh; 220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian *f = PIXEL_FORMAT_RGBA_8888; 220974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_ERROR; 221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 221274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = NO_MEMORY; 221374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 2214c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 2215c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: glReadPixels() returned %s", strerror(result)); 2216c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 221874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glEnable(GL_SCISSOR_TEST); 221974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glViewport(0, 0, hw_w, hw_h); 222074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_PROJECTION); 222174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glPopMatrix(); 222274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glMatrixMode(GL_MODELVIEW); 222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } else { 222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = BAD_VALUE; 222574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2227c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: about to release FBO resources"); 2228c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian // release FBO resources 223074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteRenderbuffersOES(1, &tname); 223274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian glDeleteFramebuffersOES(1, &name); 2233e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2234c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: about to call compositionComplete()"); 2235c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 2236e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian hw.compositionComplete(); 2237e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian 2238c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian LOGD("screenshot: result = %s", strerror(result)); 2239c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian 224074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 224374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 22441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy, 22451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap, 224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t* width, uint32_t* height, PixelFormat* format, 2247bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2248bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 22491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{ 22501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // only one display supported for now 22511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 22521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return BAD_VALUE; 22531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (!GLExtensions::getInstance().haveFramebufferObject()) 22551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return INVALID_OPERATION; 22561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian class MessageCaptureScreen : public MessageBase { 22581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian SurfaceFlinger* flinger; 22591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian DisplayID dpy; 22601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<IMemoryHeap>* heap; 22611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* w; 22621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian uint32_t* h; 22631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian PixelFormat* f; 226474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sw; 226574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian uint32_t sh; 2266bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ; 2267bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t maxLayerZ; 22681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t result; 22691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian public: 22701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2272bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t sw, uint32_t sh, 2273bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 22741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian : flinger(flinger), dpy(dpy), 2275bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2276bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2277bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian result(PERMISSION_DENIED) 22781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 22791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t getResult() const { 22811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return result; 22821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian virtual bool handler() { 22841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian Mutex::Autolock _l(flinger->mStateLock); 22851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // if we have secure windows, never allow the screen capture 22871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (flinger->mSecureFrameBuffer) 22881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 22891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 229074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian result = flinger->captureScreenImplLocked(dpy, 2291bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 22921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return true; 22941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 22951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian }; 22961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 22971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 2298bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 22991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian status_t res = postMessageSync(msg); 23001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian if (res == NO_ERROR) { 23011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 23021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 23031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return res; 23041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian} 23051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 23061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 23071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> result; 2311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian Mutex::Autolock _l(mStateLock); 2312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return result; 2314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 23157303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 2316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 231796f0819f81293076e652792794a961543e6750d7Mathias Agopian 2318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger) 2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mFlinger(flinger), mNameGenerator(1) 2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 232396f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client() 232496f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 232596f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 232696f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 232796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 232896f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 232996f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger->removeLayer(layer); 233096f0819f81293076e652792794a961543e6750d7Mathias Agopian } 2331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2333076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 233496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const { 2335b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return NO_ERROR; 2336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2337076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 233896f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = android_atomic_inc(&mNameGenerator); 234196f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.add(name, layer); 234296f0819f81293076e652792794a961543e6750d7Mathias Agopian return name; 2343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2345b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 234696f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 234796f0819f81293076e652792794a961543e6750d7Mathias Agopian // we do a linear search here, because this doesn't happen often 234896f0819f81293076e652792794a961543e6750d7Mathias Agopian const size_t count = mLayers.size(); 234996f0819f81293076e652792794a961543e6750d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 235096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (mLayers.valueAt(i) == layer) { 235196f0819f81293076e652792794a961543e6750d7Mathias Agopian mLayers.removeItemsAt(i, 1); 235296f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 235396f0819f81293076e652792794a961543e6750d7Mathias Agopian } 235496f0819f81293076e652792794a961543e6750d7Mathias Agopian } 235596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 2356076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const { 2357076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> lbc; 235896f0819f81293076e652792794a961543e6750d7Mathias Agopian const wp<LayerBaseClient>& layer(mLayers.valueFor(i)); 235996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (layer != 0) { 236096f0819f81293076e652792794a961543e6750d7Mathias Agopian lbc = layer.promote(); 236196f0819f81293076e652792794a961543e6750d7Mathias Agopian LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2362076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 2363076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return lbc; 2364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 236696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const { 2367b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2368b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2369b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const { 2370b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return -1; 2371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 237296f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface( 2373b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2374b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2375b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags) 2377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 237896f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->createSurface(this, pid, name, params, 237996f0819f81293076e652792794a961543e6750d7Mathias Agopian display, w, h, format, flags); 2380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 238196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 238296f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->removeSurface(this, sid); 2383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 238496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) { 238596f0819f81293076e652792794a961543e6750d7Mathias Agopian return mFlinger->setClientState(this, count, states); 2386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger) 2391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : ctrlblk(0), mBitmap(0), mFlinger(flinger) 2392b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2393b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int pgsize = getpagesize(); 2394b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); 2395b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2396b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mCblkHeap = new MemoryHeapBase(cblksize, 0, 2397b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian "SurfaceFlinger Client control-block"); 2398b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2399b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); 2400b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { // construct the shared structure in-place. 2401b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian new(ctrlblk) SharedClient; 2402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient() 2406b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2407b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (ctrlblk) { 2408b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ctrlblk->~SharedClient(); // destroy our shared-structure. 2409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2411b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian /* 2412b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * When a UserClient dies, it's unclear what to do exactly. 2413b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * We could go ahead and destroy all surfaces linked to that client 2414b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * however, it wouldn't be fair to the main Client 2415b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * (usually the the window-manager), which might want to re-target 2416b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * the layer to another UserClient. 2417b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * I think the best is to do nothing, or not much; in most cases the 2418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * WM itself will go ahead and clean things up when it detects a client of 2419b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * his has died. 2420b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * The remaining question is what to display? currently we keep 2421b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian * just keep the current buffer. 2422b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian */ 2423b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2425b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const { 2426b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return ctrlblk == 0 ? NO_INIT : NO_ERROR; 2427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2428b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2429b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer) 2430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = layer->getToken(); 2432b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (name >= 0) { 2433579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian int32_t mask = 1LU<<name; 2434579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { 2435579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); 2436579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2439b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2440b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const { 2441b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mCblkHeap; 2442b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2443b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2444b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const 2445b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 2446b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t name = NAME_NOT_FOUND; 2447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<Layer> layer(mFlinger->getLayer(sur)); 244889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis if (layer == 0) { 244989c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis return name; 245089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis } 2451b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2452579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // if this layer already has a token, just return it 2453b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = layer->getToken(); 245489c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis if ((name >= 0) && (layer->getClient() == this)) { 2455579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return name; 245689c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis } 2457b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2458b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = 0; 2459b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian do { 2460b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian int32_t mask = 1LU<<name; 2461b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { 2462b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // we found and locked that name 2463579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian status_t err = layer->setToken( 2464579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const_cast<UserClient*>(this), ctrlblk, name); 2465579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (err != NO_ERROR) { 2466579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian // free the name 2467579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian android_atomic_and(~mask, &mBitmap); 2468579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian name = err; 2469579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 2470b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian break; 2471b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 2472b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (++name > 31) 2473b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian name = NO_MEMORY; 2474b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } while(name >= 0); 2475b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 247653503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)", 247753503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian // sur->asBinder().get(), name, this, mBitmap); 2478b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return name; 2479b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2480b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2481b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface( 2482b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ISurfaceComposerClient::surface_data_t* params, int pid, 2483b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian const String8& name, 2484b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2485b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian uint32_t flags) { 2486b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return 0; 2487b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2488b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) { 2489b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2490b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2491b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) { 2492b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return INVALID_OPERATION; 2493b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 2494b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2495b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {} 24989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 24999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {} 25009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 25029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis PixelFormat format, uint32_t usage) { 25039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 25049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis status_t err = graphicBuffer->initCheck(); 25059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis if (err != 0) { 25069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis LOGE("createGraphicBuffer: init check failed: %d", err); 25079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 25089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } else if (graphicBuffer->handle == 0) { 25099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis LOGE("createGraphicBuffer: unable to create GraphicBuffer"); 25109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return 0; 25119a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 25129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis Mutex::Autolock _l(mLock); 25139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mBuffers.add(graphicBuffer); 25149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return graphicBuffer; 25159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 25169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennisvoid GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) { 25189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis Mutex::Autolock _l(mLock); 25199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis if (0 <= bufIdx && bufIdx < mBuffers.size()) { 25209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBuffer> b(mBuffers[bufIdx]); 25219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mBuffers.clear(); 25229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mBuffers.add(b); 25239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } else { 25249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mBuffers.clear(); 25259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis } 25269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 25279a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 25299a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane() 2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mHw(0) 2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() { 2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project delete mHw; 2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const { 2540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHw ? true : false; 2541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const { 25442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mWidth; 2545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const { 25482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian return mHeight; 25492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian} 25502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) 25522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{ 25532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHw = hw; 25542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // initialize the display orientation transform. 25562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian // it's a constant that should come from the display driver. 25572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian int displayOrientation = ISurfaceComposer::eOrientationDefault; 25582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian char property[PROPERTY_VALUE_MAX]; 25592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 25602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian //displayOrientation 25612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian switch (atoi(property)) { 25622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 90: 25632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation90; 25642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 25652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian case 270: 25662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian displayOrientation = ISurfaceComposer::eOrientation270; 25672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian break; 25682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 25692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 25702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = hw->getWidth(); 25722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = hw->getHeight(); 25732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 25742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian &mDisplayTransform); 25752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 25762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = h; 25772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = w; 25782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } else { 25792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayWidth = w; 25802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mDisplayHeight = h; 25812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 25822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 25832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian setOrientation(ISurfaceComposer::eOrientationDefault); 2584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom( 2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int orientation, int w, int h, Transform* tr) 2588eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{ 2589eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian uint32_t flags = 0; 2590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (orientation) { 2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientationDefault: 2592eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_0; 2593eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian break; 2594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation90: 2595eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_90; 2596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation180: 2598eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_180; 2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ISurfaceComposer::eOrientation270: 2601eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian flags = Transform::ROT_270; 2602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BAD_VALUE; 2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2606eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian tr->set(flags, w, h); 2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation) 2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the rotation can be handled in hardware, this is where 2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the magic should happen. 26142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const DisplayHardware& hw(displayHardware()); 26162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float w = mDisplayWidth; 26172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian const float h = mDisplayHeight; 26182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mWidth = int(w); 26192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mHeight = int(h); 26202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian 26212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian Transform orientationTransform; 2622eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian GraphicPlane::orientationToTransfrom(orientation, w, h, 2623eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian &orientationTransform); 2624eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2625eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mWidth = int(h); 2626eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian mHeight = int(w); 2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2628eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian 26290d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mOrientation = orientation; 26302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mGlobalTransform = mDisplayTransform * orientationTransform; 2631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const { 2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *mHw; 2636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 263859119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() { 263959119e658a12279e8fff508f8773843de2d90917Mathias Agopian return *mHw; 264059119e658a12279e8fff508f8773843de2d90917Mathias Agopian} 264159119e658a12279e8fff508f8773843de2d90917Mathias Agopian 2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const { 2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mGlobalTransform; 2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2646076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const { 2647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mHw->getEGLDisplay(); 2648076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 2649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 2653