SurfaceFlinger.cpp revision 0dfb7b73a468698622d6c0423f0d5471a6f5d375
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 1452b0e73443ff8da195fbf0df851a028e07a691b2Ben Cheng * limitations under the License. 1552b0e73443ff8da195fbf0df851a028e07a691b2Ben Cheng */ 1652b0e73443ff8da195fbf0df851a028e07a691b2Ben Cheng 1752b0e73443ff8da195fbf0df851a028e07a691b2Ben Cheng#include <stdlib.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <errno.h> 231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <math.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <limits.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 28864c0d50cda714d73fa70e3600ec36b5db8a835aMathias Agopian 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/log.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h> 3169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn 321c4907ee77392afb768c2f088e0dedbe4239f6fbJack Palevich#include <binder/IPCThreadState.h> 331c4907ee77392afb768c2f088e0dedbe4239f6fbJack Palevich#include <binder/IServiceManager.h> 341c4907ee77392afb768c2f088e0dedbe4239f6fbJack Palevich#include <binder/MemoryHeapBase.h> 351c4907ee77392afb768c2f088e0dedbe4239f6fbJack Palevich#include <binder/PermissionCache.h> 36560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 385a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <utils/String16.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/StopWatch.h> 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/GraphicBufferAllocator.h> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/GraphicLog.h> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/PixelFormat.h> 44b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <pixelflinger/pixelflinger.h> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "clz.h" 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "GLExtensions.h" 5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "DdmConnection.h" 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "Layer.h" 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "LayerDim.h" 53dae8e94cce0881f3e10ef5e34b881f512bb52a75Doug Felt#include "LayerScreenshot.h" 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SurfaceFlinger.h" 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/HWComposer.h" 58fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <private/surfaceflinger/SharedBufferStack.h> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* ideally AID_GRAPHICS would be in a semi-public header 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or there would be a way to map a user/group name to its id 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef AID_GRAPHICS 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define AID_GRAPHICS 1003 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 672b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DISPLAY_COUNT 1 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16 sDump("android.permission.DUMP"); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : BnSurfaceComposer(), Thread(false), 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTransactionFlags(0), 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResizeTransationPending(false), 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayersRemoved(false), 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBootTime(systemTime()), 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVisibleRegionsDirty(false), 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHwWorkListDirty(false), 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeDisplay(false), 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mElectronBeamAnimationMode(0), 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeCount(0), 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeDisplayTime(0), 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugRegion(0), 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugBackground(0), 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugDDMS(0), 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugDisableHWC(0), 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugDisableTransformHint(0), 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugInSwapBuffers(0), 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastSwapBufferTime(0), 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugInTransaction(0), 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastTransactionTime(0), 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBootFinished(false), 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConsoleSignals(0), 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSecureFrameBuffer(0) 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project init(); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid SurfaceFlinger::init() 109bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen{ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("SurfaceFlinger is starting"); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // debugging stuff... 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugRegion = atoi(value); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project property_get("debug.sf.showbackground", value, "0"); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugBackground = atoi(value); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project property_get("debug.sf.ddms", value, "0"); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDebugDDMS = atoi(value); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDebugDDMS) { 1240b6955a48bad9aee01ae2f0c06d3f168ca603ab7Nick Pelly DdmConnection::start(getServiceName()); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 126bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI_IF(mDebugRegion, "showupdates enabled"); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI_IF(mDebugBackground, "showbackground enabled"); 129ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate LOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 133b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato{ 1341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato glDeleteTextures(1, &mWormholeTexName); 135d2110dbce071a236b6176de344ca797b737542ebJoe Onorato} 1364ababd922eac5931e0222862ff082dc29e012816Joe Onorato 13702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootsp<IMemoryHeap> SurfaceFlinger::getCblk() const 13802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root{ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mServerHeap; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<ISurfaceComposerClient> bclient; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<Client> client(new Client(this)); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = client->initCheck(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err == NO_ERROR) { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bclient = client; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bclient; 151c70e06bbfac0d92ec218a32e35d9d7fa80f23cc9Mike Reed} 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gba; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 160bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen{ 161b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const GraphicPlane& plane(mGraphicPlanes[dpy]); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return plane; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 16825ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian return const_cast<GraphicPlane&>( 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1711bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 172000479f9e325b4e426a67033abd92d47da412725Mathias Agopianvoid SurfaceFlinger::bootFinished() 173000479f9e325b4e426a67033abd92d47da412725Mathias Agopian{ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const nsecs_t now = systemTime(); 175b5af325fb1d21a9295bf3009cc95e5ead4999247Mike Reed const nsecs_t duration = now - mBootTime; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBootFinished = true; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait patiently for the window manager death 180560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich const String16 name("window"); 181a6276fdd4253c3a7150ab675678c750473ab6c45Jack Palevich sp<IBinder> window(defaultServiceManager()->getService(name)); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (window != 0) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project window->linkToDeath(this); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // stop boot animation 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project property_set("ctl.stop", "bootanim"); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 190bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 191bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the window manager died on us. prepare its eulogy. 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unfreeze the screen in case it was... frozen 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeDisplayTime = 0; 196b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mFreezeCount = 0; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFreezeDisplay = false; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset screen orientation 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setOrientation(0, eOrientationDefault, 0); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // restart the boot-animation 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project property_set("ctl.start", "bootanim"); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid SurfaceFlinger::onFirstRef() 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wait for the main thread to be done with its initialization 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReadyToRunBarrier.wait(); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (r<<11)|(g<<5)|b; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun() 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI( "SurfaceFlinger's main thread ready to run. " 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Initializing graphics H/W..."); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we only support one display currently 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dpy = 0; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 226 { 227 // initialize the main display 228 GraphicPlane& plane(graphicPlane(dpy)); 229 DisplayHardware* const hw = new DisplayHardware(this, dpy); 230 plane.setDisplayHardware(hw); 231 } 232 233 // create the shared control-block 234 mServerHeap = new MemoryHeapBase(4096, 235 MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 236 LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 237 238 mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 239 LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 240 241 new(mServerCblk) surface_flinger_cblk_t; 242 243 // initialize primary screen 244 // (other display should be initialized in the same manner, but 245 // asynchronously, as they could come and go. None of this is supported 246 // yet). 247 const GraphicPlane& plane(graphicPlane(dpy)); 248 const DisplayHardware& hw = plane.displayHardware(); 249 const uint32_t w = hw.getWidth(); 250 const uint32_t h = hw.getHeight(); 251 const uint32_t f = hw.getFormat(); 252 hw.makeCurrent(); 253 254 // initialize the shared control block 255 mServerCblk->connected |= 1<<dpy; 256 display_cblk_t* dcblk = mServerCblk->displays + dpy; 257 memset(dcblk, 0, sizeof(display_cblk_t)); 258 dcblk->w = plane.getWidth(); 259 dcblk->h = plane.getHeight(); 260 dcblk->format = f; 261 dcblk->orientation = ISurfaceComposer::eOrientationDefault; 262 dcblk->xdpi = hw.getDpiX(); 263 dcblk->ydpi = hw.getDpiY(); 264 dcblk->fps = hw.getRefreshRate(); 265 dcblk->density = hw.getDensity(); 266 267 // Initialize OpenGL|ES 268 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 269 glPixelStorei(GL_PACK_ALIGNMENT, 4); 270 glEnableClientState(GL_VERTEX_ARRAY); 271 glEnable(GL_SCISSOR_TEST); 272 glShadeModel(GL_FLAT); 273 glDisable(GL_DITHER); 274 glDisable(GL_CULL_FACE); 275 276 const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 277 const uint16_t g1 = pack565(0x17,0x2f,0x17); 278 const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; 279 glGenTextures(1, &mWormholeTexName); 280 glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 281 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 282 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 283 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 284 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 285 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 286 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); 287 288 const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 289 glGenTextures(1, &mProtectedTexName); 290 glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 291 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 292 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 293 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 294 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 295 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 296 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 297 298 glViewport(0, 0, w, h); 299 glMatrixMode(GL_PROJECTION); 300 glLoadIdentity(); 301 // put the origin in the left-bottom corner 302 glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 303 304 mReadyToRunBarrier.open(); 305 306 /* 307 * We're now ready to accept clients... 308 */ 309 310 // start boot animation 311 property_set("ctl.start", "bootanim"); 312 313 return NO_ERROR; 314} 315 316// ---------------------------------------------------------------------------- 317#if 0 318#pragma mark - 319#pragma mark Events Handler 320#endif 321 322void SurfaceFlinger::waitForEvent() 323{ 324 while (true) { 325 nsecs_t timeout = -1; 326 const nsecs_t freezeDisplayTimeout = ms2ns(5000); 327 if (UNLIKELY(isFrozen())) { 328 // wait 5 seconds 329 const nsecs_t now = systemTime(); 330 if (mFreezeDisplayTime == 0) { 331 mFreezeDisplayTime = now; 332 } 333 nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 334 timeout = waitTime>0 ? waitTime : 0; 335 } 336 337 sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 338 339 // see if we timed out 340 if (isFrozen()) { 341 const nsecs_t now = systemTime(); 342 nsecs_t frozenTime = (now - mFreezeDisplayTime); 343 if (frozenTime >= freezeDisplayTimeout) { 344 // we timed out and are still frozen 345 LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 346 mFreezeDisplay, mFreezeCount); 347 mFreezeDisplayTime = 0; 348 mFreezeCount = 0; 349 mFreezeDisplay = false; 350 } 351 } 352 353 if (msg != 0) { 354 switch (msg->what) { 355 case MessageQueue::INVALIDATE: 356 // invalidate message, just return to the main loop 357 return; 358 } 359 } 360 } 361} 362 363void SurfaceFlinger::signalEvent() { 364 mEventQueue.invalidate(); 365} 366 367bool SurfaceFlinger::authenticateSurfaceTexture( 368 const sp<ISurfaceTexture>& surfaceTexture) const { 369 Mutex::Autolock _l(mStateLock); 370 sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 371 372 // Check the visible layer list for the ISurface 373 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 374 size_t count = currentLayers.size(); 375 for (size_t i=0 ; i<count ; i++) { 376 const sp<LayerBase>& layer(currentLayers[i]); 377 sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 378 if (lbc != NULL) { 379 wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 380 if (lbcBinder == surfaceTextureBinder) { 381 return true; 382 } 383 } 384 } 385 386 // Check the layers in the purgatory. This check is here so that if a 387 // SurfaceTexture gets destroyed before all the clients are done using it, 388 // the error will not be reported as "surface XYZ is not authenticated", but 389 // will instead fail later on when the client tries to use the surface, 390 // which should be reported as "surface XYZ returned an -ENODEV". The 391 // purgatorized layers are no less authentic than the visible ones, so this 392 // should not cause any harm. 393 size_t purgatorySize = mLayerPurgatory.size(); 394 for (size_t i=0 ; i<purgatorySize ; i++) { 395 const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 396 sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 397 if (lbc != NULL) { 398 wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 399 if (lbcBinder == surfaceTextureBinder) { 400 return true; 401 } 402 } 403 } 404 405 return false; 406} 407 408status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 409 nsecs_t reltime, uint32_t flags) 410{ 411 return mEventQueue.postMessage(msg, reltime, flags); 412} 413 414status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 415 nsecs_t reltime, uint32_t flags) 416{ 417 status_t res = mEventQueue.postMessage(msg, reltime, flags); 418 if (res == NO_ERROR) { 419 msg->wait(); 420 } 421 return res; 422} 423 424// ---------------------------------------------------------------------------- 425#if 0 426#pragma mark - 427#pragma mark Main loop 428#endif 429 430bool SurfaceFlinger::threadLoop() 431{ 432 waitForEvent(); 433 434 // check for transactions 435 if (UNLIKELY(mConsoleSignals)) { 436 handleConsoleEvents(); 437 } 438 439 // if we're in a global transaction, don't do anything. 440 const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 441 uint32_t transactionFlags = peekTransactionFlags(mask); 442 if (UNLIKELY(transactionFlags)) { 443 handleTransaction(transactionFlags); 444 } 445 446 // post surfaces (if needed) 447 handlePageFlip(); 448 449 if (mDirtyRegion.isEmpty()) { 450 // nothing new to do. 451 return true; 452 } 453 454 if (UNLIKELY(mHwWorkListDirty)) { 455 // build the h/w work list 456 handleWorkList(); 457 } 458 459 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 460 if (LIKELY(hw.canDraw())) { 461 // repaint the framebuffer (if needed) 462 463 const int index = hw.getCurrentBufferIndex(); 464 GraphicLog& logger(GraphicLog::getInstance()); 465 466 logger.log(GraphicLog::SF_REPAINT, index); 467 handleRepaint(); 468 469 // inform the h/w that we're done compositing 470 logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 471 hw.compositionComplete(); 472 473 logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 474 postFramebuffer(); 475 476 logger.log(GraphicLog::SF_REPAINT_DONE, index); 477 } else { 478 // pretend we did the post 479 hw.compositionComplete(); 480 usleep(16667); // 60 fps period 481 } 482 return true; 483} 484 485void SurfaceFlinger::postFramebuffer() 486{ 487 // this should never happen. we do the flip anyways so we don't 488 // risk to cause a deadlock with hwc 489 LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty"); 490 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 491 const nsecs_t now = systemTime(); 492 mDebugInSwapBuffers = now; 493 hw.flip(mSwapRegion); 494 mLastSwapBufferTime = systemTime() - now; 495 mDebugInSwapBuffers = 0; 496 mSwapRegion.clear(); 497} 498 499void SurfaceFlinger::handleConsoleEvents() 500{ 501 // something to do with the console 502 const DisplayHardware& hw = graphicPlane(0).displayHardware(); 503 504 int what = android_atomic_and(0, &mConsoleSignals); 505 if (what & eConsoleAcquired) { 506 hw.acquireScreen(); 507 // this is a temporary work-around, eventually this should be called 508 // by the power-manager 509 SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 510 } 511 512 if (what & eConsoleReleased) { 513 if (hw.isScreenAcquired()) { 514 hw.releaseScreen(); 515 } 516 } 517 518 mDirtyRegion.set(hw.bounds()); 519} 520 521void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 522{ 523 Mutex::Autolock _l(mStateLock); 524 const nsecs_t now = systemTime(); 525 mDebugInTransaction = now; 526 527 // Here we're guaranteed that some transaction flags are set 528 // so we can call handleTransactionLocked() unconditionally. 529 // We call getTransactionFlags(), which will also clear the flags, 530 // with mStateLock held to guarantee that mCurrentState won't change 531 // until the transaction is committed. 532 533 const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 534 transactionFlags = getTransactionFlags(mask); 535 handleTransactionLocked(transactionFlags); 536 537 mLastTransactionTime = systemTime() - now; 538 mDebugInTransaction = 0; 539 invalidateHwcGeometry(); 540 // here the transaction has been committed 541} 542 543void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 544{ 545 const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 546 const size_t count = currentLayers.size(); 547 548 /* 549 * Traversal of the children 550 * (perform the transaction for each of them if needed) 551 */ 552 553 const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 554 if (layersNeedTransaction) { 555 for (size_t i=0 ; i<count ; i++) { 556 const sp<LayerBase>& layer = currentLayers[i]; 557 uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 558 if (!trFlags) continue; 559 560 const uint32_t flags = layer->doTransaction(0); 561 if (flags & Layer::eVisibleRegion) 562 mVisibleRegionsDirty = true; 563 } 564 } 565 566 /* 567 * Perform our own transaction if needed 568 */ 569 570 if (transactionFlags & eTransactionNeeded) { 571 if (mCurrentState.orientation != mDrawingState.orientation) { 572 // the orientation has changed, recompute all visible regions 573 // and invalidate everything. 574 575 const int dpy = 0; 576 const int orientation = mCurrentState.orientation; 577 // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; 578 GraphicPlane& plane(graphicPlane(dpy)); 579 plane.setOrientation(orientation); 580 581 // update the shared control block 582 const DisplayHardware& hw(plane.displayHardware()); 583 volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 584 dcblk->orientation = orientation; 585 dcblk->w = plane.getWidth(); 586 dcblk->h = plane.getHeight(); 587 588 mVisibleRegionsDirty = true; 589 mDirtyRegion.set(hw.bounds()); 590 } 591 592 if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 593 // freezing or unfreezing the display -> trigger animation if needed 594 mFreezeDisplay = mCurrentState.freezeDisplay; 595 if (mFreezeDisplay) 596 mFreezeDisplayTime = 0; 597 } 598 599 if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 600 // layers have been added 601 mVisibleRegionsDirty = true; 602 } 603 604 // some layers might have been removed, so 605 // we need to update the regions they're exposing. 606 if (mLayersRemoved) { 607 mLayersRemoved = false; 608 mVisibleRegionsDirty = true; 609 const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 610 const size_t count = previousLayers.size(); 611 for (size_t i=0 ; i<count ; i++) { 612 const sp<LayerBase>& layer(previousLayers[i]); 613 if (currentLayers.indexOf( layer ) < 0) { 614 // this layer is not visible anymore 615 mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 616 } 617 } 618 } 619 } 620 621 commitTransaction(); 622} 623 624sp<FreezeLock> SurfaceFlinger::getFreezeLock() const 625{ 626 return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 627} 628 629void SurfaceFlinger::computeVisibleRegions( 630 const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 631{ 632 const GraphicPlane& plane(graphicPlane(0)); 633 const Transform& planeTransform(plane.transform()); 634 const DisplayHardware& hw(plane.displayHardware()); 635 const Region screenRegion(hw.bounds()); 636 637 Region aboveOpaqueLayers; 638 Region aboveCoveredLayers; 639 Region dirty; 640 641 bool secureFrameBuffer = false; 642 643 size_t i = currentLayers.size(); 644 while (i--) { 645 const sp<LayerBase>& layer = currentLayers[i]; 646 layer->validateVisibility(planeTransform); 647 648 // start with the whole surface at its current location 649 const Layer::State& s(layer->drawingState()); 650 651 /* 652 * opaqueRegion: area of a surface that is fully opaque. 653 */ 654 Region opaqueRegion; 655 656 /* 657 * visibleRegion: area of a surface that is visible on screen 658 * and not fully transparent. This is essentially the layer's 659 * footprint minus the opaque regions above it. 660 * Areas covered by a translucent surface are considered visible. 661 */ 662 Region visibleRegion; 663 664 /* 665 * coveredRegion: area of a surface that is covered by all 666 * visible regions above it (which includes the translucent areas). 667 */ 668 Region coveredRegion; 669 670 671 // handle hidden surfaces by setting the visible region to empty 672 if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 673 const bool translucent = !layer->isOpaque(); 674 const Rect bounds(layer->visibleBounds()); 675 visibleRegion.set(bounds); 676 visibleRegion.andSelf(screenRegion); 677 if (!visibleRegion.isEmpty()) { 678 // Remove the transparent area from the visible region 679 if (translucent) { 680 visibleRegion.subtractSelf(layer->transparentRegionScreen); 681 } 682 683 // compute the opaque region 684 const int32_t layerOrientation = layer->getOrientation(); 685 if (s.alpha==255 && !translucent && 686 ((layerOrientation & Transform::ROT_INVALID) == false)) { 687 // the opaque region is the layer's footprint 688 opaqueRegion = visibleRegion; 689 } 690 } 691 } 692 693 // Clip the covered region to the visible region 694 coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 695 696 // Update aboveCoveredLayers for next (lower) layer 697 aboveCoveredLayers.orSelf(visibleRegion); 698 699 // subtract the opaque region covered by the layers above us 700 visibleRegion.subtractSelf(aboveOpaqueLayers); 701 702 // compute this layer's dirty region 703 if (layer->contentDirty) { 704 // we need to invalidate the whole region 705 dirty = visibleRegion; 706 // as well, as the old visible region 707 dirty.orSelf(layer->visibleRegionScreen); 708 layer->contentDirty = false; 709 } else { 710 /* compute the exposed region: 711 * the exposed region consists of two components: 712 * 1) what's VISIBLE now and was COVERED before 713 * 2) what's EXPOSED now less what was EXPOSED before 714 * 715 * note that (1) is conservative, we start with the whole 716 * visible region but only keep what used to be covered by 717 * something -- which mean it may have been exposed. 718 * 719 * (2) handles areas that were not covered by anything but got 720 * exposed because of a resize. 721 */ 722 const Region newExposed = visibleRegion - coveredRegion; 723 const Region oldVisibleRegion = layer->visibleRegionScreen; 724 const Region oldCoveredRegion = layer->coveredRegionScreen; 725 const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 726 dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 727 } 728 dirty.subtractSelf(aboveOpaqueLayers); 729 730 // accumulate to the screen dirty region 731 dirtyRegion.orSelf(dirty); 732 733 // Update aboveOpaqueLayers for next (lower) layer 734 aboveOpaqueLayers.orSelf(opaqueRegion); 735 736 // Store the visible region is screen space 737 layer->setVisibleRegion(visibleRegion); 738 layer->setCoveredRegion(coveredRegion); 739 740 // If a secure layer is partially visible, lock-down the screen! 741 if (layer->isSecure() && !visibleRegion.isEmpty()) { 742 secureFrameBuffer = true; 743 } 744 } 745 746 // invalidate the areas where a layer was removed 747 dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 748 mDirtyRegionRemovedLayer.clear(); 749 750 mSecureFrameBuffer = secureFrameBuffer; 751 opaqueRegion = aboveOpaqueLayers; 752} 753 754 755void SurfaceFlinger::commitTransaction() 756{ 757 mDrawingState = mCurrentState; 758 mResizeTransationPending = false; 759 mTransactionCV.broadcast(); 760} 761 762void SurfaceFlinger::handlePageFlip() 763{ 764 bool visibleRegions = mVisibleRegionsDirty; 765 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 766 visibleRegions |= lockPageFlip(currentLayers); 767 768 const DisplayHardware& hw = graphicPlane(0).displayHardware(); 769 const Region screenRegion(hw.bounds()); 770 if (visibleRegions) { 771 Region opaqueRegion; 772 computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 773 774 /* 775 * rebuild the visible layer list 776 */ 777 const size_t count = currentLayers.size(); 778 mVisibleLayersSortedByZ.clear(); 779 mVisibleLayersSortedByZ.setCapacity(count); 780 for (size_t i=0 ; i<count ; i++) { 781 if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 782 mVisibleLayersSortedByZ.add(currentLayers[i]); 783 } 784 785 mWormholeRegion = screenRegion.subtract(opaqueRegion); 786 mVisibleRegionsDirty = false; 787 invalidateHwcGeometry(); 788 } 789 790 unlockPageFlip(currentLayers); 791 792 mDirtyRegion.orSelf(getAndClearInvalidateRegion()); 793 mDirtyRegion.andSelf(screenRegion); 794} 795 796void SurfaceFlinger::invalidateHwcGeometry() 797{ 798 mHwWorkListDirty = true; 799} 800 801bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 802{ 803 bool recomputeVisibleRegions = false; 804 size_t count = currentLayers.size(); 805 sp<LayerBase> const* layers = currentLayers.array(); 806 for (size_t i=0 ; i<count ; i++) { 807 const sp<LayerBase>& layer(layers[i]); 808 layer->lockPageFlip(recomputeVisibleRegions); 809 } 810 return recomputeVisibleRegions; 811} 812 813void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 814{ 815 const GraphicPlane& plane(graphicPlane(0)); 816 const Transform& planeTransform(plane.transform()); 817 size_t count = currentLayers.size(); 818 sp<LayerBase> const* layers = currentLayers.array(); 819 for (size_t i=0 ; i<count ; i++) { 820 const sp<LayerBase>& layer(layers[i]); 821 layer->unlockPageFlip(planeTransform, mDirtyRegion); 822 } 823} 824 825void SurfaceFlinger::handleWorkList() 826{ 827 mHwWorkListDirty = false; 828 HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 829 if (hwc.initCheck() == NO_ERROR) { 830 const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 831 const size_t count = currentLayers.size(); 832 hwc.createWorkList(count); 833 hwc_layer_t* const cur(hwc.getLayers()); 834 for (size_t i=0 ; cur && i<count ; i++) { 835 currentLayers[i]->setGeometry(&cur[i]); 836 if (mDebugDisableHWC || mDebugRegion) { 837 cur[i].compositionType = HWC_FRAMEBUFFER; 838 cur[i].flags |= HWC_SKIP_LAYER; 839 } 840 } 841 } 842} 843 844void SurfaceFlinger::handleRepaint() 845{ 846 // compute the invalid region 847 mSwapRegion.orSelf(mDirtyRegion); 848 849 if (UNLIKELY(mDebugRegion)) { 850 debugFlashRegions(); 851 } 852 853 // set the frame buffer 854 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 855 glMatrixMode(GL_MODELVIEW); 856 glLoadIdentity(); 857 858 uint32_t flags = hw.getFlags(); 859 if ((flags & DisplayHardware::SWAP_RECTANGLE) || 860 (flags & DisplayHardware::BUFFER_PRESERVED)) 861 { 862 // we can redraw only what's dirty, but since SWAP_RECTANGLE only 863 // takes a rectangle, we must make sure to update that whole 864 // rectangle in that case 865 if (flags & DisplayHardware::SWAP_RECTANGLE) { 866 // TODO: we really should be able to pass a region to 867 // SWAP_RECTANGLE so that we don't have to redraw all this. 868 mDirtyRegion.set(mSwapRegion.bounds()); 869 } else { 870 // in the BUFFER_PRESERVED case, obviously, we can update only 871 // what's needed and nothing more. 872 // NOTE: this is NOT a common case, as preserving the backbuffer 873 // is costly and usually involves copying the whole update back. 874 } 875 } else { 876 if (flags & DisplayHardware::PARTIAL_UPDATES) { 877 // We need to redraw the rectangle that will be updated 878 // (pushed to the framebuffer). 879 // This is needed because PARTIAL_UPDATES only takes one 880 // rectangle instead of a region (see DisplayHardware::flip()) 881 mDirtyRegion.set(mSwapRegion.bounds()); 882 } else { 883 // we need to redraw everything (the whole screen) 884 mDirtyRegion.set(hw.bounds()); 885 mSwapRegion = mDirtyRegion; 886 } 887 } 888 889 setupHardwareComposer(mDirtyRegion); 890 composeSurfaces(mDirtyRegion); 891 892 // update the swap region and clear the dirty region 893 mSwapRegion.orSelf(mDirtyRegion); 894 mDirtyRegion.clear(); 895} 896 897void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) 898{ 899 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 900 HWComposer& hwc(hw.getHwComposer()); 901 hwc_layer_t* const cur(hwc.getLayers()); 902 if (!cur) { 903 return; 904 } 905 906 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 907 size_t count = layers.size(); 908 909 LOGE_IF(hwc.getNumLayers() != count, 910 "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 911 hwc.getNumLayers(), count); 912 913 // just to be extra-safe, use the smallest count 914 if (hwc.initCheck() == NO_ERROR) { 915 count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 916 } 917 918 /* 919 * update the per-frame h/w composer data for each layer 920 * and build the transparent region of the FB 921 */ 922 for (size_t i=0 ; i<count ; i++) { 923 const sp<LayerBase>& layer(layers[i]); 924 layer->setPerFrameData(&cur[i]); 925 } 926 const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 927 status_t err = hwc.prepare(); 928 LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 929 930 if (err == NO_ERROR) { 931 // what's happening here is tricky. 932 // we want to clear all the layers with the CLEAR_FB flags 933 // that are opaque. 934 // however, since some GPU are efficient at preserving 935 // the backbuffer, we want to take advantage of that so we do the 936 // clear only in the dirty region (other areas will be preserved 937 // on those GPUs). 938 // NOTE: on non backbuffer preserving GPU, the dirty region 939 // has already been expanded as needed, so the code is correct 940 // there too. 941 // 942 // However, the content of the framebuffer cannot be trusted when 943 // we switch to/from FB/OVERLAY, in which case we need to 944 // expand the dirty region to those areas too. 945 // 946 // Note also that there is a special case when switching from 947 // "no layers in FB" to "some layers in FB", where we need to redraw 948 // the entire FB, since some areas might contain uninitialized 949 // data. 950 // 951 // Also we want to make sure to not clear areas that belong to 952 // layers above that won't redraw (we would just be erasing them), 953 // that is, we can't erase anything outside the dirty region. 954 955 Region transparent; 956 957 if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { 958 transparent.set(hw.getBounds()); 959 dirtyInOut = transparent; 960 } else { 961 for (size_t i=0 ; i<count ; i++) { 962 const sp<LayerBase>& layer(layers[i]); 963 if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { 964 transparent.orSelf(layer->visibleRegionScreen); 965 } 966 bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); 967 if (isOverlay != layer->isOverlay()) { 968 // we transitioned to/from overlay, so add this layer 969 // to the dirty region so the framebuffer can be either 970 // cleared or redrawn. 971 dirtyInOut.orSelf(layer->visibleRegionScreen); 972 } 973 layer->setOverlay(isOverlay); 974 } 975 // don't erase stuff outside the dirty region 976 transparent.andSelf(dirtyInOut); 977 } 978 979 /* 980 * clear the area of the FB that need to be transparent 981 */ 982 if (!transparent.isEmpty()) { 983 glClearColor(0,0,0,0); 984 Region::const_iterator it = transparent.begin(); 985 Region::const_iterator const end = transparent.end(); 986 const int32_t height = hw.getHeight(); 987 while (it != end) { 988 const Rect& r(*it++); 989 const GLint sy = height - (r.top + r.height()); 990 glScissor(r.left, sy, r.width(), r.height()); 991 glClear(GL_COLOR_BUFFER_BIT); 992 } 993 } 994 } 995} 996 997void SurfaceFlinger::composeSurfaces(const Region& dirty) 998{ 999 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1000 HWComposer& hwc(hw.getHwComposer()); 1001 1002 const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); 1003 if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) { 1004 // should never happen unless the window manager has a bug 1005 // draw something... 1006 drawWormhole(); 1007 } 1008 1009 /* 1010 * and then, render the layers targeted at the framebuffer 1011 */ 1012 hwc_layer_t* const cur(hwc.getLayers()); 1013 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1014 size_t count = layers.size(); 1015 for (size_t i=0 ; i<count ; i++) { 1016 if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { 1017 continue; 1018 } 1019 const sp<LayerBase>& layer(layers[i]); 1020 const Region clip(dirty.intersect(layer->visibleRegionScreen)); 1021 if (!clip.isEmpty()) { 1022 layer->draw(clip); 1023 } 1024 } 1025} 1026 1027void SurfaceFlinger::debugFlashRegions() 1028{ 1029 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1030 const uint32_t flags = hw.getFlags(); 1031 const int32_t height = hw.getHeight(); 1032 if (mSwapRegion.isEmpty()) { 1033 return; 1034 } 1035 1036 if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 1037 (flags & DisplayHardware::BUFFER_PRESERVED))) { 1038 const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 1039 mDirtyRegion.bounds() : hw.bounds()); 1040 composeSurfaces(repaint); 1041 } 1042 1043 glDisable(GL_TEXTURE_EXTERNAL_OES); 1044 glDisable(GL_TEXTURE_2D); 1045 glDisable(GL_BLEND); 1046 glDisable(GL_SCISSOR_TEST); 1047 1048 static int toggle = 0; 1049 toggle = 1 - toggle; 1050 if (toggle) { 1051 glColor4f(1, 0, 1, 1); 1052 } else { 1053 glColor4f(1, 1, 0, 1); 1054 } 1055 1056 Region::const_iterator it = mDirtyRegion.begin(); 1057 Region::const_iterator const end = mDirtyRegion.end(); 1058 while (it != end) { 1059 const Rect& r = *it++; 1060 GLfloat vertices[][2] = { 1061 { r.left, height - r.top }, 1062 { r.left, height - r.bottom }, 1063 { r.right, height - r.bottom }, 1064 { r.right, height - r.top } 1065 }; 1066 glVertexPointer(2, GL_FLOAT, 0, vertices); 1067 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1068 } 1069 1070 hw.flip(mSwapRegion); 1071 1072 if (mDebugRegion > 1) 1073 usleep(mDebugRegion * 1000); 1074 1075 glEnable(GL_SCISSOR_TEST); 1076} 1077 1078void SurfaceFlinger::drawWormhole() const 1079{ 1080 const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1081 if (region.isEmpty()) 1082 return; 1083 1084 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1085 const int32_t width = hw.getWidth(); 1086 const int32_t height = hw.getHeight(); 1087 1088 if (LIKELY(!mDebugBackground)) { 1089 glClearColor(0,0,0,0); 1090 Region::const_iterator it = region.begin(); 1091 Region::const_iterator const end = region.end(); 1092 while (it != end) { 1093 const Rect& r = *it++; 1094 const GLint sy = height - (r.top + r.height()); 1095 glScissor(r.left, sy, r.width(), r.height()); 1096 glClear(GL_COLOR_BUFFER_BIT); 1097 } 1098 } else { 1099 const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1100 { width, height }, { 0, height } }; 1101 const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1102 1103 glVertexPointer(2, GL_SHORT, 0, vertices); 1104 glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1105 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1106 1107 glDisable(GL_TEXTURE_EXTERNAL_OES); 1108 glEnable(GL_TEXTURE_2D); 1109 glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1110 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1111 glMatrixMode(GL_TEXTURE); 1112 glLoadIdentity(); 1113 1114 glDisable(GL_BLEND); 1115 1116 glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 1117 Region::const_iterator it = region.begin(); 1118 Region::const_iterator const end = region.end(); 1119 while (it != end) { 1120 const Rect& r = *it++; 1121 const GLint sy = height - (r.top + r.height()); 1122 glScissor(r.left, sy, r.width(), r.height()); 1123 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1124 } 1125 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1126 glDisable(GL_TEXTURE_2D); 1127 glLoadIdentity(); 1128 glMatrixMode(GL_MODELVIEW); 1129 } 1130} 1131 1132void SurfaceFlinger::debugShowFPS() const 1133{ 1134 static int mFrameCount; 1135 static int mLastFrameCount = 0; 1136 static nsecs_t mLastFpsTime = 0; 1137 static float mFps = 0; 1138 mFrameCount++; 1139 nsecs_t now = systemTime(); 1140 nsecs_t diff = now - mLastFpsTime; 1141 if (diff > ms2ns(250)) { 1142 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1143 mLastFpsTime = now; 1144 mLastFrameCount = mFrameCount; 1145 } 1146 // XXX: mFPS has the value we want 1147 } 1148 1149status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1150{ 1151 Mutex::Autolock _l(mStateLock); 1152 addLayer_l(layer); 1153 setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1154 return NO_ERROR; 1155} 1156 1157status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1158{ 1159 ssize_t i = mCurrentState.layersSortedByZ.add(layer); 1160 return (i < 0) ? status_t(i) : status_t(NO_ERROR); 1161} 1162 1163ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 1164 const sp<LayerBaseClient>& lbc) 1165{ 1166 // attach this layer to the client 1167 size_t name = client->attachLayer(lbc); 1168 1169 Mutex::Autolock _l(mStateLock); 1170 1171 // add this layer to the current state list 1172 addLayer_l(lbc); 1173 1174 return ssize_t(name); 1175} 1176 1177status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 1178{ 1179 Mutex::Autolock _l(mStateLock); 1180 status_t err = purgatorizeLayer_l(layer); 1181 if (err == NO_ERROR) 1182 setTransactionFlags(eTransactionNeeded); 1183 return err; 1184} 1185 1186status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1187{ 1188 sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1189 if (lbc != 0) { 1190 mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1191 } 1192 ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1193 if (index >= 0) { 1194 mLayersRemoved = true; 1195 return NO_ERROR; 1196 } 1197 return status_t(index); 1198} 1199 1200status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 1201{ 1202 // First add the layer to the purgatory list, which makes sure it won't 1203 // go away, then remove it from the main list (through a transaction). 1204 ssize_t err = removeLayer_l(layerBase); 1205 if (err >= 0) { 1206 mLayerPurgatory.add(layerBase); 1207 } 1208 1209 layerBase->onRemoved(); 1210 1211 // it's possible that we don't find a layer, because it might 1212 // have been destroyed already -- this is not technically an error 1213 // from the user because there is a race between Client::destroySurface(), 1214 // ~Client() and ~ISurface(). 1215 return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 1216} 1217 1218status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1219{ 1220 layer->forceVisibilityTransaction(); 1221 setTransactionFlags(eTraversalNeeded); 1222 return NO_ERROR; 1223} 1224 1225uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1226{ 1227 return android_atomic_release_load(&mTransactionFlags); 1228} 1229 1230uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1231{ 1232 return android_atomic_and(~flags, &mTransactionFlags) & flags; 1233} 1234 1235uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1236{ 1237 uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1238 if ((old & flags)==0) { // wake the server up 1239 signalEvent(); 1240 } 1241 return old; 1242} 1243 1244 1245void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, 1246 int orientation) { 1247 Mutex::Autolock _l(mStateLock); 1248 1249 uint32_t flags = 0; 1250 if (mCurrentState.orientation != orientation) { 1251 if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1252 mCurrentState.orientation = orientation; 1253 flags |= eTransactionNeeded; 1254 mResizeTransationPending = true; 1255 } else if (orientation != eOrientationUnchanged) { 1256 LOGW("setTransactionState: ignoring unrecognized orientation: %d", 1257 orientation); 1258 } 1259 } 1260 1261 const size_t count = state.size(); 1262 for (size_t i=0 ; i<count ; i++) { 1263 const ComposerState& s(state[i]); 1264 sp<Client> client( static_cast<Client *>(s.client.get()) ); 1265 flags |= setClientStateLocked(client, s.state); 1266 } 1267 if (flags) { 1268 setTransactionFlags(flags); 1269 } 1270 1271 signalEvent(); 1272 1273 // if there is a transaction with a resize, wait for it to 1274 // take effect before returning. 1275 while (mResizeTransationPending) { 1276 status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1277 if (CC_UNLIKELY(err != NO_ERROR)) { 1278 // just in case something goes wrong in SF, return to the 1279 // called after a few seconds. 1280 LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1281 mResizeTransationPending = false; 1282 break; 1283 } 1284 } 1285} 1286 1287status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1288{ 1289 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1290 return BAD_VALUE; 1291 1292 Mutex::Autolock _l(mStateLock); 1293 mCurrentState.freezeDisplay = 1; 1294 setTransactionFlags(eTransactionNeeded); 1295 1296 // flags is intended to communicate some sort of animation behavior 1297 // (for instance fading) 1298 return NO_ERROR; 1299} 1300 1301status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1302{ 1303 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1304 return BAD_VALUE; 1305 1306 Mutex::Autolock _l(mStateLock); 1307 mCurrentState.freezeDisplay = 0; 1308 setTransactionFlags(eTransactionNeeded); 1309 1310 // flags is intended to communicate some sort of animation behavior 1311 // (for instance fading) 1312 return NO_ERROR; 1313} 1314 1315int SurfaceFlinger::setOrientation(DisplayID dpy, 1316 int orientation, uint32_t flags) 1317{ 1318 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1319 return BAD_VALUE; 1320 1321 Mutex::Autolock _l(mStateLock); 1322 if (mCurrentState.orientation != orientation) { 1323 if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1324 mCurrentState.orientationFlags = flags; 1325 mCurrentState.orientation = orientation; 1326 setTransactionFlags(eTransactionNeeded); 1327 mTransactionCV.wait(mStateLock); 1328 } else { 1329 orientation = BAD_VALUE; 1330 } 1331 } 1332 return orientation; 1333} 1334 1335sp<ISurface> SurfaceFlinger::createSurface( 1336 ISurfaceComposerClient::surface_data_t* params, 1337 const String8& name, 1338 const sp<Client>& client, 1339 DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1340 uint32_t flags) 1341{ 1342 sp<LayerBaseClient> layer; 1343 sp<ISurface> surfaceHandle; 1344 1345 if (int32_t(w|h) < 0) { 1346 LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 1347 int(w), int(h)); 1348 return surfaceHandle; 1349 } 1350 1351 //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1352 sp<Layer> normalLayer; 1353 switch (flags & eFXSurfaceMask) { 1354 case eFXSurfaceNormal: 1355 normalLayer = createNormalSurface(client, d, w, h, flags, format); 1356 layer = normalLayer; 1357 break; 1358 case eFXSurfaceBlur: 1359 // for now we treat Blur as Dim, until we can implement it 1360 // efficiently. 1361 case eFXSurfaceDim: 1362 layer = createDimSurface(client, d, w, h, flags); 1363 break; 1364 case eFXSurfaceScreenshot: 1365 layer = createScreenshotSurface(client, d, w, h, flags); 1366 break; 1367 } 1368 1369 if (layer != 0) { 1370 layer->initStates(w, h, flags); 1371 layer->setName(name); 1372 ssize_t token = addClientLayer(client, layer); 1373 1374 surfaceHandle = layer->getSurface(); 1375 if (surfaceHandle != 0) { 1376 params->token = token; 1377 params->identity = layer->getIdentity(); 1378 if (normalLayer != 0) { 1379 Mutex::Autolock _l(mStateLock); 1380 mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1381 } 1382 } 1383 1384 setTransactionFlags(eTransactionNeeded); 1385 } 1386 1387 return surfaceHandle; 1388} 1389 1390sp<Layer> SurfaceFlinger::createNormalSurface( 1391 const sp<Client>& client, DisplayID display, 1392 uint32_t w, uint32_t h, uint32_t flags, 1393 PixelFormat& format) 1394{ 1395 // initialize the surfaces 1396 switch (format) { // TODO: take h/w into account 1397 case PIXEL_FORMAT_TRANSPARENT: 1398 case PIXEL_FORMAT_TRANSLUCENT: 1399 format = PIXEL_FORMAT_RGBA_8888; 1400 break; 1401 case PIXEL_FORMAT_OPAQUE: 1402#ifdef NO_RGBX_8888 1403 format = PIXEL_FORMAT_RGB_565; 1404#else 1405 format = PIXEL_FORMAT_RGBX_8888; 1406#endif 1407 break; 1408 } 1409 1410#ifdef NO_RGBX_8888 1411 if (format == PIXEL_FORMAT_RGBX_8888) 1412 format = PIXEL_FORMAT_RGBA_8888; 1413#endif 1414 1415 sp<Layer> layer = new Layer(this, display, client); 1416 status_t err = layer->setBuffers(w, h, format, flags); 1417 if (LIKELY(err != NO_ERROR)) { 1418 LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1419 layer.clear(); 1420 } 1421 return layer; 1422} 1423 1424sp<LayerDim> SurfaceFlinger::createDimSurface( 1425 const sp<Client>& client, DisplayID display, 1426 uint32_t w, uint32_t h, uint32_t flags) 1427{ 1428 sp<LayerDim> layer = new LayerDim(this, display, client); 1429 return layer; 1430} 1431 1432sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( 1433 const sp<Client>& client, DisplayID display, 1434 uint32_t w, uint32_t h, uint32_t flags) 1435{ 1436 sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); 1437 status_t err = layer->capture(); 1438 if (err != NO_ERROR) { 1439 layer.clear(); 1440 LOGW("createScreenshotSurface failed (%s)", strerror(-err)); 1441 } 1442 return layer; 1443} 1444 1445status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 1446{ 1447 /* 1448 * called by the window manager, when a surface should be marked for 1449 * destruction. 1450 * 1451 * The surface is removed from the current and drawing lists, but placed 1452 * in the purgatory queue, so it's not destroyed right-away (we need 1453 * to wait for all client's references to go away first). 1454 */ 1455 1456 status_t err = NAME_NOT_FOUND; 1457 Mutex::Autolock _l(mStateLock); 1458 sp<LayerBaseClient> layer = client->getLayerUser(sid); 1459 if (layer != 0) { 1460 err = purgatorizeLayer_l(layer); 1461 if (err == NO_ERROR) { 1462 setTransactionFlags(eTransactionNeeded); 1463 } 1464 } 1465 return err; 1466} 1467 1468status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1469{ 1470 // called by ~ISurface() when all references are gone 1471 status_t err = NO_ERROR; 1472 sp<LayerBaseClient> l(layer.promote()); 1473 if (l != NULL) { 1474 Mutex::Autolock _l(mStateLock); 1475 err = removeLayer_l(l); 1476 if (err == NAME_NOT_FOUND) { 1477 // The surface wasn't in the current list, which means it was 1478 // removed already, which means it is in the purgatory, 1479 // and need to be removed from there. 1480 ssize_t idx = mLayerPurgatory.remove(l); 1481 LOGE_IF(idx < 0, 1482 "layer=%p is not in the purgatory list", l.get()); 1483 } 1484 LOGE_IF(err<0 && err != NAME_NOT_FOUND, 1485 "error removing layer=%p (%s)", l.get(), strerror(-err)); 1486 } 1487 return err; 1488} 1489 1490uint32_t SurfaceFlinger::setClientStateLocked( 1491 const sp<Client>& client, 1492 const layer_state_t& s) 1493{ 1494 uint32_t flags = 0; 1495 sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1496 if (layer != 0) { 1497 const uint32_t what = s.what; 1498 if (what & ePositionChanged) { 1499 if (layer->setPosition(s.x, s.y)) 1500 flags |= eTraversalNeeded; 1501 } 1502 if (what & eLayerChanged) { 1503 ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1504 if (layer->setLayer(s.z)) { 1505 mCurrentState.layersSortedByZ.removeAt(idx); 1506 mCurrentState.layersSortedByZ.add(layer); 1507 // we need traversal (state changed) 1508 // AND transaction (list changed) 1509 flags |= eTransactionNeeded|eTraversalNeeded; 1510 } 1511 } 1512 if (what & eSizeChanged) { 1513 if (layer->setSize(s.w, s.h)) { 1514 flags |= eTraversalNeeded; 1515 mResizeTransationPending = true; 1516 } 1517 } 1518 if (what & eAlphaChanged) { 1519 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1520 flags |= eTraversalNeeded; 1521 } 1522 if (what & eMatrixChanged) { 1523 if (layer->setMatrix(s.matrix)) 1524 flags |= eTraversalNeeded; 1525 } 1526 if (what & eTransparentRegionChanged) { 1527 if (layer->setTransparentRegionHint(s.transparentRegion)) 1528 flags |= eTraversalNeeded; 1529 } 1530 if (what & eVisibilityChanged) { 1531 if (layer->setFlags(s.flags, s.mask)) 1532 flags |= eTraversalNeeded; 1533 } 1534 } 1535 return flags; 1536} 1537 1538void SurfaceFlinger::screenReleased(int dpy) 1539{ 1540 // this may be called by a signal handler, we can't do too much in here 1541 android_atomic_or(eConsoleReleased, &mConsoleSignals); 1542 signalEvent(); 1543} 1544 1545void SurfaceFlinger::screenAcquired(int dpy) 1546{ 1547 // this may be called by a signal handler, we can't do too much in here 1548 android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1549 signalEvent(); 1550} 1551 1552status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1553{ 1554 const size_t SIZE = 4096; 1555 char buffer[SIZE]; 1556 String8 result; 1557 1558 if (!PermissionCache::checkCallingPermission(sDump)) { 1559 snprintf(buffer, SIZE, "Permission Denial: " 1560 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1561 IPCThreadState::self()->getCallingPid(), 1562 IPCThreadState::self()->getCallingUid()); 1563 result.append(buffer); 1564 } else { 1565 1566 // figure out if we're stuck somewhere 1567 const nsecs_t now = systemTime(); 1568 const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 1569 const nsecs_t inTransaction(mDebugInTransaction); 1570 nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 1571 nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1572 1573 // Try to get the main lock, but don't insist if we can't 1574 // (this would indicate SF is stuck, but we want to be able to 1575 // print something in dumpsys). 1576 int retry = 3; 1577 while (mStateLock.tryLock()<0 && --retry>=0) { 1578 usleep(1000000); 1579 } 1580 const bool locked(retry >= 0); 1581 if (!locked) { 1582 snprintf(buffer, SIZE, 1583 "SurfaceFlinger appears to be unresponsive, " 1584 "dumping anyways (no locks held)\n"); 1585 result.append(buffer); 1586 } 1587 1588 /* 1589 * Dump the visible layer list 1590 */ 1591 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1592 const size_t count = currentLayers.size(); 1593 snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 1594 result.append(buffer); 1595 for (size_t i=0 ; i<count ; i++) { 1596 const sp<LayerBase>& layer(currentLayers[i]); 1597 layer->dump(result, buffer, SIZE); 1598 const Layer::State& s(layer->drawingState()); 1599 s.transparentRegion.dump(result, "transparentRegion"); 1600 layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1601 layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1602 } 1603 1604 /* 1605 * Dump the layers in the purgatory 1606 */ 1607 1608 const size_t purgatorySize = mLayerPurgatory.size(); 1609 snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 1610 result.append(buffer); 1611 for (size_t i=0 ; i<purgatorySize ; i++) { 1612 const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 1613 layer->shortDump(result, buffer, SIZE); 1614 } 1615 1616 /* 1617 * Dump SurfaceFlinger global state 1618 */ 1619 1620 snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 1621 result.append(buffer); 1622 1623 const GLExtensions& extensions(GLExtensions::getInstance()); 1624 snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 1625 extensions.getVendor(), 1626 extensions.getRenderer(), 1627 extensions.getVersion()); 1628 result.append(buffer); 1629 snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 1630 result.append(buffer); 1631 1632 mWormholeRegion.dump(result, "WormholeRegion"); 1633 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1634 snprintf(buffer, SIZE, 1635 " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1636 mFreezeDisplay?"yes":"no", mFreezeCount, 1637 mCurrentState.orientation, hw.canDraw()); 1638 result.append(buffer); 1639 snprintf(buffer, SIZE, 1640 " last eglSwapBuffers() time: %f us\n" 1641 " last transaction time : %f us\n" 1642 " refresh-rate : %f fps\n" 1643 " x-dpi : %f\n" 1644 " y-dpi : %f\n", 1645 mLastSwapBufferTime/1000.0, 1646 mLastTransactionTime/1000.0, 1647 hw.getRefreshRate(), 1648 hw.getDpiX(), 1649 hw.getDpiY()); 1650 result.append(buffer); 1651 1652 if (inSwapBuffersDuration || !locked) { 1653 snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 1654 inSwapBuffersDuration/1000.0); 1655 result.append(buffer); 1656 } 1657 1658 if (inTransactionDuration || !locked) { 1659 snprintf(buffer, SIZE, " transaction time: %f us\n", 1660 inTransactionDuration/1000.0); 1661 result.append(buffer); 1662 } 1663 1664 /* 1665 * Dump HWComposer state 1666 */ 1667 HWComposer& hwc(hw.getHwComposer()); 1668 snprintf(buffer, SIZE, " h/w composer %s and %s\n", 1669 hwc.initCheck()==NO_ERROR ? "present" : "not present", 1670 (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 1671 result.append(buffer); 1672 hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); 1673 1674 /* 1675 * Dump gralloc state 1676 */ 1677 const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1678 alloc.dump(result); 1679 hw.dump(result); 1680 1681 if (locked) { 1682 mStateLock.unlock(); 1683 } 1684 } 1685 write(fd, result.string(), result.size()); 1686 return NO_ERROR; 1687} 1688 1689status_t SurfaceFlinger::onTransact( 1690 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1691{ 1692 switch (code) { 1693 case CREATE_CONNECTION: 1694 case SET_TRANSACTION_STATE: 1695 case SET_ORIENTATION: 1696 case FREEZE_DISPLAY: 1697 case UNFREEZE_DISPLAY: 1698 case BOOT_FINISHED: 1699 case TURN_ELECTRON_BEAM_OFF: 1700 case TURN_ELECTRON_BEAM_ON: 1701 { 1702 // codes that require permission check 1703 IPCThreadState* ipc = IPCThreadState::self(); 1704 const int pid = ipc->getCallingPid(); 1705 const int uid = ipc->getCallingUid(); 1706 if ((uid != AID_GRAPHICS) && 1707 !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1708 LOGE("Permission Denial: " 1709 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1710 return PERMISSION_DENIED; 1711 } 1712 break; 1713 } 1714 case CAPTURE_SCREEN: 1715 { 1716 // codes that require permission check 1717 IPCThreadState* ipc = IPCThreadState::self(); 1718 const int pid = ipc->getCallingPid(); 1719 const int uid = ipc->getCallingUid(); 1720 if ((uid != AID_GRAPHICS) && 1721 !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1722 LOGE("Permission Denial: " 1723 "can't read framebuffer pid=%d, uid=%d", pid, uid); 1724 return PERMISSION_DENIED; 1725 } 1726 break; 1727 } 1728 } 1729 1730 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1731 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1732 CHECK_INTERFACE(ISurfaceComposer, data, reply); 1733 if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1734 IPCThreadState* ipc = IPCThreadState::self(); 1735 const int pid = ipc->getCallingPid(); 1736 const int uid = ipc->getCallingUid(); 1737 LOGE("Permission Denial: " 1738 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1739 return PERMISSION_DENIED; 1740 } 1741 int n; 1742 switch (code) { 1743 case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 1744 case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1745 return NO_ERROR; 1746 case 1002: // SHOW_UPDATES 1747 n = data.readInt32(); 1748 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 1749 invalidateHwcGeometry(); 1750 repaintEverything(); 1751 return NO_ERROR; 1752 case 1003: // SHOW_BACKGROUND 1753 n = data.readInt32(); 1754 mDebugBackground = n ? 1 : 0; 1755 return NO_ERROR; 1756 case 1004:{ // repaint everything 1757 repaintEverything(); 1758 return NO_ERROR; 1759 } 1760 case 1005:{ // force transaction 1761 setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1762 return NO_ERROR; 1763 } 1764 case 1006:{ // enable/disable GraphicLog 1765 int enabled = data.readInt32(); 1766 GraphicLog::getInstance().setEnabled(enabled); 1767 return NO_ERROR; 1768 } 1769 case 1007: // set mFreezeCount 1770 mFreezeCount = data.readInt32(); 1771 mFreezeDisplayTime = 0; 1772 return NO_ERROR; 1773 case 1008: // toggle use of hw composer 1774 n = data.readInt32(); 1775 mDebugDisableHWC = n ? 1 : 0; 1776 invalidateHwcGeometry(); 1777 repaintEverything(); 1778 return NO_ERROR; 1779 case 1009: // toggle use of transform hint 1780 n = data.readInt32(); 1781 mDebugDisableTransformHint = n ? 1 : 0; 1782 invalidateHwcGeometry(); 1783 repaintEverything(); 1784 return NO_ERROR; 1785 case 1010: // interrogate. 1786 reply->writeInt32(0); 1787 reply->writeInt32(0); 1788 reply->writeInt32(mDebugRegion); 1789 reply->writeInt32(mDebugBackground); 1790 return NO_ERROR; 1791 case 1013: { 1792 Mutex::Autolock _l(mStateLock); 1793 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1794 reply->writeInt32(hw.getPageFlipCount()); 1795 } 1796 return NO_ERROR; 1797 } 1798 } 1799 return err; 1800} 1801 1802void SurfaceFlinger::repaintEverything() { 1803 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1804 const Rect bounds(hw.getBounds()); 1805 setInvalidateRegion(Region(bounds)); 1806 signalEvent(); 1807} 1808 1809void SurfaceFlinger::setInvalidateRegion(const Region& reg) { 1810 Mutex::Autolock _l(mInvalidateLock); 1811 mInvalidateRegion = reg; 1812} 1813 1814Region SurfaceFlinger::getAndClearInvalidateRegion() { 1815 Mutex::Autolock _l(mInvalidateLock); 1816 Region reg(mInvalidateRegion); 1817 mInvalidateRegion.clear(); 1818 return reg; 1819} 1820 1821// --------------------------------------------------------------------------- 1822 1823status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, 1824 GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1825{ 1826 Mutex::Autolock _l(mStateLock); 1827 return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); 1828} 1829 1830status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 1831 GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1832{ 1833 if (!GLExtensions::getInstance().haveFramebufferObject()) 1834 return INVALID_OPERATION; 1835 1836 // get screen geometry 1837 const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 1838 const uint32_t hw_w = hw.getWidth(); 1839 const uint32_t hw_h = hw.getHeight(); 1840 GLfloat u = 1; 1841 GLfloat v = 1; 1842 1843 // make sure to clear all GL error flags 1844 while ( glGetError() != GL_NO_ERROR ) ; 1845 1846 // create a FBO 1847 GLuint name, tname; 1848 glGenTextures(1, &tname); 1849 glBindTexture(GL_TEXTURE_2D, tname); 1850 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1851 hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1852 if (glGetError() != GL_NO_ERROR) { 1853 while ( glGetError() != GL_NO_ERROR ) ; 1854 GLint tw = (2 << (31 - clz(hw_w))); 1855 GLint th = (2 << (31 - clz(hw_h))); 1856 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1857 tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1858 u = GLfloat(hw_w) / tw; 1859 v = GLfloat(hw_h) / th; 1860 } 1861 glGenFramebuffersOES(1, &name); 1862 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 1863 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 1864 GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 1865 1866 // redraw the screen entirely... 1867 glDisable(GL_TEXTURE_EXTERNAL_OES); 1868 glDisable(GL_TEXTURE_2D); 1869 glClearColor(0,0,0,1); 1870 glClear(GL_COLOR_BUFFER_BIT); 1871 glMatrixMode(GL_MODELVIEW); 1872 glLoadIdentity(); 1873 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1874 const size_t count = layers.size(); 1875 for (size_t i=0 ; i<count ; ++i) { 1876 const sp<LayerBase>& layer(layers[i]); 1877 layer->drawForSreenShot(); 1878 } 1879 1880 hw.compositionComplete(); 1881 1882 // back to main framebuffer 1883 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 1884 glDisable(GL_SCISSOR_TEST); 1885 glDeleteFramebuffersOES(1, &name); 1886 1887 *textureName = tname; 1888 *uOut = u; 1889 *vOut = v; 1890 return NO_ERROR; 1891} 1892 1893// --------------------------------------------------------------------------- 1894 1895status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 1896{ 1897 // get screen geometry 1898 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1899 const uint32_t hw_w = hw.getWidth(); 1900 const uint32_t hw_h = hw.getHeight(); 1901 const Region screenBounds(hw.getBounds()); 1902 1903 GLfloat u, v; 1904 GLuint tname; 1905 status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); 1906 if (result != NO_ERROR) { 1907 return result; 1908 } 1909 1910 GLfloat vtx[8]; 1911 const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; 1912 glBindTexture(GL_TEXTURE_2D, tname); 1913 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1914 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1915 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1916 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 1917 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1918 glVertexPointer(2, GL_FLOAT, 0, vtx); 1919 1920 /* 1921 * Texture coordinate mapping 1922 * 1923 * u 1924 * 1 +----------+---+ 1925 * | | | | image is inverted 1926 * | V | | w.r.t. the texture 1927 * 1-v +----------+ | coordinates 1928 * | | 1929 * | | 1930 * | | 1931 * 0 +--------------+ 1932 * 0 1 1933 * 1934 */ 1935 1936 class s_curve_interpolator { 1937 const float nbFrames, s, v; 1938 public: 1939 s_curve_interpolator(int nbFrames, float s) 1940 : nbFrames(1.0f / (nbFrames-1)), s(s), 1941 v(1.0f + expf(-s + 0.5f*s)) { 1942 } 1943 float operator()(int f) { 1944 const float x = f * nbFrames; 1945 return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 1946 } 1947 }; 1948 1949 class v_stretch { 1950 const GLfloat hw_w, hw_h; 1951 public: 1952 v_stretch(uint32_t hw_w, uint32_t hw_h) 1953 : hw_w(hw_w), hw_h(hw_h) { 1954 } 1955 void operator()(GLfloat* vtx, float v) { 1956 const GLfloat w = hw_w + (hw_w * v); 1957 const GLfloat h = hw_h - (hw_h * v); 1958 const GLfloat x = (hw_w - w) * 0.5f; 1959 const GLfloat y = (hw_h - h) * 0.5f; 1960 vtx[0] = x; vtx[1] = y; 1961 vtx[2] = x; vtx[3] = y + h; 1962 vtx[4] = x + w; vtx[5] = y + h; 1963 vtx[6] = x + w; vtx[7] = y; 1964 } 1965 }; 1966 1967 class h_stretch { 1968 const GLfloat hw_w, hw_h; 1969 public: 1970 h_stretch(uint32_t hw_w, uint32_t hw_h) 1971 : hw_w(hw_w), hw_h(hw_h) { 1972 } 1973 void operator()(GLfloat* vtx, float v) { 1974 const GLfloat w = hw_w - (hw_w * v); 1975 const GLfloat h = 1.0f; 1976 const GLfloat x = (hw_w - w) * 0.5f; 1977 const GLfloat y = (hw_h - h) * 0.5f; 1978 vtx[0] = x; vtx[1] = y; 1979 vtx[2] = x; vtx[3] = y + h; 1980 vtx[4] = x + w; vtx[5] = y + h; 1981 vtx[6] = x + w; vtx[7] = y; 1982 } 1983 }; 1984 1985 // the full animation is 24 frames 1986 char value[PROPERTY_VALUE_MAX]; 1987 property_get("debug.sf.electron_frames", value, "24"); 1988 int nbFrames = (atoi(value) + 1) >> 1; 1989 if (nbFrames <= 0) // just in case 1990 nbFrames = 24; 1991 1992 s_curve_interpolator itr(nbFrames, 7.5f); 1993 s_curve_interpolator itg(nbFrames, 8.0f); 1994 s_curve_interpolator itb(nbFrames, 8.5f); 1995 1996 v_stretch vverts(hw_w, hw_h); 1997 1998 glMatrixMode(GL_TEXTURE); 1999 glLoadIdentity(); 2000 glMatrixMode(GL_MODELVIEW); 2001 glLoadIdentity(); 2002 2003 glEnable(GL_BLEND); 2004 glBlendFunc(GL_ONE, GL_ONE); 2005 for (int i=0 ; i<nbFrames ; i++) { 2006 float x, y, w, h; 2007 const float vr = itr(i); 2008 const float vg = itg(i); 2009 const float vb = itb(i); 2010 2011 // clear screen 2012 glColorMask(1,1,1,1); 2013 glClear(GL_COLOR_BUFFER_BIT); 2014 glEnable(GL_TEXTURE_2D); 2015 2016 // draw the red plane 2017 vverts(vtx, vr); 2018 glColorMask(1,0,0,1); 2019 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2020 2021 // draw the green plane 2022 vverts(vtx, vg); 2023 glColorMask(0,1,0,1); 2024 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2025 2026 // draw the blue plane 2027 vverts(vtx, vb); 2028 glColorMask(0,0,1,1); 2029 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2030 2031 // draw the white highlight (we use the last vertices) 2032 glDisable(GL_TEXTURE_2D); 2033 glColorMask(1,1,1,1); 2034 glColor4f(vg, vg, vg, 1); 2035 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2036 hw.flip(screenBounds); 2037 } 2038 2039 h_stretch hverts(hw_w, hw_h); 2040 glDisable(GL_BLEND); 2041 glDisable(GL_TEXTURE_2D); 2042 glColorMask(1,1,1,1); 2043 for (int i=0 ; i<nbFrames ; i++) { 2044 const float v = itg(i); 2045 hverts(vtx, v); 2046 glClear(GL_COLOR_BUFFER_BIT); 2047 glColor4f(1-v, 1-v, 1-v, 1); 2048 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2049 hw.flip(screenBounds); 2050 } 2051 2052 glColorMask(1,1,1,1); 2053 glEnable(GL_SCISSOR_TEST); 2054 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 2055 glDeleteTextures(1, &tname); 2056 glDisable(GL_TEXTURE_2D); 2057 glDisable(GL_BLEND); 2058 return NO_ERROR; 2059} 2060 2061status_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 2062{ 2063 status_t result = PERMISSION_DENIED; 2064 2065 if (!GLExtensions::getInstance().haveFramebufferObject()) 2066 return INVALID_OPERATION; 2067 2068 2069 // get screen geometry 2070 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 2071 const uint32_t hw_w = hw.getWidth(); 2072 const uint32_t hw_h = hw.getHeight(); 2073 const Region screenBounds(hw.bounds()); 2074 2075 GLfloat u, v; 2076 GLuint tname; 2077 result = renderScreenToTextureLocked(0, &tname, &u, &v); 2078 if (result != NO_ERROR) { 2079 return result; 2080 } 2081 2082 GLfloat vtx[8]; 2083 const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 2084 glBindTexture(GL_TEXTURE_2D, tname); 2085 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 2086 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 2087 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2088 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 2089 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 2090 glVertexPointer(2, GL_FLOAT, 0, vtx); 2091 2092 class s_curve_interpolator { 2093 const float nbFrames, s, v; 2094 public: 2095 s_curve_interpolator(int nbFrames, float s) 2096 : nbFrames(1.0f / (nbFrames-1)), s(s), 2097 v(1.0f + expf(-s + 0.5f*s)) { 2098 } 2099 float operator()(int f) { 2100 const float x = f * nbFrames; 2101 return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 2102 } 2103 }; 2104 2105 class v_stretch { 2106 const GLfloat hw_w, hw_h; 2107 public: 2108 v_stretch(uint32_t hw_w, uint32_t hw_h) 2109 : hw_w(hw_w), hw_h(hw_h) { 2110 } 2111 void operator()(GLfloat* vtx, float v) { 2112 const GLfloat w = hw_w + (hw_w * v); 2113 const GLfloat h = hw_h - (hw_h * v); 2114 const GLfloat x = (hw_w - w) * 0.5f; 2115 const GLfloat y = (hw_h - h) * 0.5f; 2116 vtx[0] = x; vtx[1] = y; 2117 vtx[2] = x; vtx[3] = y + h; 2118 vtx[4] = x + w; vtx[5] = y + h; 2119 vtx[6] = x + w; vtx[7] = y; 2120 } 2121 }; 2122 2123 class h_stretch { 2124 const GLfloat hw_w, hw_h; 2125 public: 2126 h_stretch(uint32_t hw_w, uint32_t hw_h) 2127 : hw_w(hw_w), hw_h(hw_h) { 2128 } 2129 void operator()(GLfloat* vtx, float v) { 2130 const GLfloat w = hw_w - (hw_w * v); 2131 const GLfloat h = 1.0f; 2132 const GLfloat x = (hw_w - w) * 0.5f; 2133 const GLfloat y = (hw_h - h) * 0.5f; 2134 vtx[0] = x; vtx[1] = y; 2135 vtx[2] = x; vtx[3] = y + h; 2136 vtx[4] = x + w; vtx[5] = y + h; 2137 vtx[6] = x + w; vtx[7] = y; 2138 } 2139 }; 2140 2141 // the full animation is 12 frames 2142 int nbFrames = 8; 2143 s_curve_interpolator itr(nbFrames, 7.5f); 2144 s_curve_interpolator itg(nbFrames, 8.0f); 2145 s_curve_interpolator itb(nbFrames, 8.5f); 2146 2147 h_stretch hverts(hw_w, hw_h); 2148 glDisable(GL_BLEND); 2149 glDisable(GL_TEXTURE_2D); 2150 glColorMask(1,1,1,1); 2151 for (int i=nbFrames-1 ; i>=0 ; i--) { 2152 const float v = itg(i); 2153 hverts(vtx, v); 2154 glClear(GL_COLOR_BUFFER_BIT); 2155 glColor4f(1-v, 1-v, 1-v, 1); 2156 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2157 hw.flip(screenBounds); 2158 } 2159 2160 nbFrames = 4; 2161 v_stretch vverts(hw_w, hw_h); 2162 glEnable(GL_BLEND); 2163 glBlendFunc(GL_ONE, GL_ONE); 2164 for (int i=nbFrames-1 ; i>=0 ; i--) { 2165 float x, y, w, h; 2166 const float vr = itr(i); 2167 const float vg = itg(i); 2168 const float vb = itb(i); 2169 2170 // clear screen 2171 glColorMask(1,1,1,1); 2172 glClear(GL_COLOR_BUFFER_BIT); 2173 glEnable(GL_TEXTURE_2D); 2174 2175 // draw the red plane 2176 vverts(vtx, vr); 2177 glColorMask(1,0,0,1); 2178 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2179 2180 // draw the green plane 2181 vverts(vtx, vg); 2182 glColorMask(0,1,0,1); 2183 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2184 2185 // draw the blue plane 2186 vverts(vtx, vb); 2187 glColorMask(0,0,1,1); 2188 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2189 2190 hw.flip(screenBounds); 2191 } 2192 2193 glColorMask(1,1,1,1); 2194 glEnable(GL_SCISSOR_TEST); 2195 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 2196 glDeleteTextures(1, &tname); 2197 glDisable(GL_TEXTURE_2D); 2198 glDisable(GL_BLEND); 2199 2200 return NO_ERROR; 2201} 2202 2203// --------------------------------------------------------------------------- 2204 2205status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 2206{ 2207 DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 2208 if (!hw.canDraw()) { 2209 // we're already off 2210 return NO_ERROR; 2211 } 2212 2213 // turn off hwc while we're doing the animation 2214 hw.getHwComposer().disable(); 2215 // and make sure to turn it back on (if needed) next time we compose 2216 invalidateHwcGeometry(); 2217 2218 if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2219 electronBeamOffAnimationImplLocked(); 2220 } 2221 2222 // always clear the whole screen at the end of the animation 2223 glClearColor(0,0,0,1); 2224 glDisable(GL_SCISSOR_TEST); 2225 glClear(GL_COLOR_BUFFER_BIT); 2226 glEnable(GL_SCISSOR_TEST); 2227 hw.flip( Region(hw.bounds()) ); 2228 2229 return NO_ERROR; 2230} 2231 2232status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 2233{ 2234 class MessageTurnElectronBeamOff : public MessageBase { 2235 SurfaceFlinger* flinger; 2236 int32_t mode; 2237 status_t result; 2238 public: 2239 MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2240 : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 2241 } 2242 status_t getResult() const { 2243 return result; 2244 } 2245 virtual bool handler() { 2246 Mutex::Autolock _l(flinger->mStateLock); 2247 result = flinger->turnElectronBeamOffImplLocked(mode); 2248 return true; 2249 } 2250 }; 2251 2252 sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 2253 status_t res = postMessageSync(msg); 2254 if (res == NO_ERROR) { 2255 res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 2256 2257 // work-around: when the power-manager calls us we activate the 2258 // animation. eventually, the "on" animation will be called 2259 // by the power-manager itself 2260 mElectronBeamAnimationMode = mode; 2261 } 2262 return res; 2263} 2264 2265// --------------------------------------------------------------------------- 2266 2267status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 2268{ 2269 DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 2270 if (hw.canDraw()) { 2271 // we're already on 2272 return NO_ERROR; 2273 } 2274 if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2275 electronBeamOnAnimationImplLocked(); 2276 } 2277 2278 // make sure to redraw the whole screen when the animation is done 2279 mDirtyRegion.set(hw.bounds()); 2280 signalEvent(); 2281 2282 return NO_ERROR; 2283} 2284 2285status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 2286{ 2287 class MessageTurnElectronBeamOn : public MessageBase { 2288 SurfaceFlinger* flinger; 2289 int32_t mode; 2290 status_t result; 2291 public: 2292 MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2293 : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 2294 } 2295 status_t getResult() const { 2296 return result; 2297 } 2298 virtual bool handler() { 2299 Mutex::Autolock _l(flinger->mStateLock); 2300 result = flinger->turnElectronBeamOnImplLocked(mode); 2301 return true; 2302 } 2303 }; 2304 2305 postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 2306 return NO_ERROR; 2307} 2308 2309// --------------------------------------------------------------------------- 2310 2311status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 2312 sp<IMemoryHeap>* heap, 2313 uint32_t* w, uint32_t* h, PixelFormat* f, 2314 uint32_t sw, uint32_t sh, 2315 uint32_t minLayerZ, uint32_t maxLayerZ) 2316{ 2317 status_t result = PERMISSION_DENIED; 2318 2319 // only one display supported for now 2320 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 2321 return BAD_VALUE; 2322 2323 if (!GLExtensions::getInstance().haveFramebufferObject()) 2324 return INVALID_OPERATION; 2325 2326 // get screen geometry 2327 const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 2328 const uint32_t hw_w = hw.getWidth(); 2329 const uint32_t hw_h = hw.getHeight(); 2330 2331 if ((sw > hw_w) || (sh > hw_h)) 2332 return BAD_VALUE; 2333 2334 sw = (!sw) ? hw_w : sw; 2335 sh = (!sh) ? hw_h : sh; 2336 const size_t size = sw * sh * 4; 2337 2338 //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2339 // sw, sh, minLayerZ, maxLayerZ); 2340 2341 // make sure to clear all GL error flags 2342 while ( glGetError() != GL_NO_ERROR ) ; 2343 2344 // create a FBO 2345 GLuint name, tname; 2346 glGenRenderbuffersOES(1, &tname); 2347 glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 2348 glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2349 glGenFramebuffersOES(1, &name); 2350 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 2351 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 2352 GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 2353 2354 GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2355 2356 if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 2357 2358 // invert everything, b/c glReadPixel() below will invert the FB 2359 glViewport(0, 0, sw, sh); 2360 glScissor(0, 0, sw, sh); 2361 glEnable(GL_SCISSOR_TEST); 2362 glMatrixMode(GL_PROJECTION); 2363 glPushMatrix(); 2364 glLoadIdentity(); 2365 glOrthof(0, hw_w, hw_h, 0, 0, 1); 2366 glMatrixMode(GL_MODELVIEW); 2367 2368 // redraw the screen entirely... 2369 glClearColor(0,0,0,1); 2370 glClear(GL_COLOR_BUFFER_BIT); 2371 2372 const LayerVector& layers(mDrawingState.layersSortedByZ); 2373 const size_t count = layers.size(); 2374 for (size_t i=0 ; i<count ; ++i) { 2375 const sp<LayerBase>& layer(layers[i]); 2376 const uint32_t flags = layer->drawingState().flags; 2377 if (!(flags & ISurfaceComposer::eLayerHidden)) { 2378 const uint32_t z = layer->drawingState().z; 2379 if (z >= minLayerZ && z <= maxLayerZ) { 2380 layer->drawForSreenShot(); 2381 } 2382 } 2383 } 2384 2385 // XXX: this is needed on tegra 2386 glEnable(GL_SCISSOR_TEST); 2387 glScissor(0, 0, sw, sh); 2388 2389 // check for errors and return screen capture 2390 if (glGetError() != GL_NO_ERROR) { 2391 // error while rendering 2392 result = INVALID_OPERATION; 2393 } else { 2394 // allocate shared memory large enough to hold the 2395 // screen capture 2396 sp<MemoryHeapBase> base( 2397 new MemoryHeapBase(size, 0, "screen-capture") ); 2398 void* const ptr = base->getBase(); 2399 if (ptr) { 2400 // capture the screen with glReadPixels() 2401 glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 2402 if (glGetError() == GL_NO_ERROR) { 2403 *heap = base; 2404 *w = sw; 2405 *h = sh; 2406 *f = PIXEL_FORMAT_RGBA_8888; 2407 result = NO_ERROR; 2408 } 2409 } else { 2410 result = NO_MEMORY; 2411 } 2412 } 2413 glEnable(GL_SCISSOR_TEST); 2414 glViewport(0, 0, hw_w, hw_h); 2415 glMatrixMode(GL_PROJECTION); 2416 glPopMatrix(); 2417 glMatrixMode(GL_MODELVIEW); 2418 } else { 2419 result = BAD_VALUE; 2420 } 2421 2422 // release FBO resources 2423 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 2424 glDeleteRenderbuffersOES(1, &tname); 2425 glDeleteFramebuffersOES(1, &name); 2426 2427 hw.compositionComplete(); 2428 2429 // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2430 2431 return result; 2432} 2433 2434 2435status_t SurfaceFlinger::captureScreen(DisplayID dpy, 2436 sp<IMemoryHeap>* heap, 2437 uint32_t* width, uint32_t* height, PixelFormat* format, 2438 uint32_t sw, uint32_t sh, 2439 uint32_t minLayerZ, uint32_t maxLayerZ) 2440{ 2441 // only one display supported for now 2442 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 2443 return BAD_VALUE; 2444 2445 if (!GLExtensions::getInstance().haveFramebufferObject()) 2446 return INVALID_OPERATION; 2447 2448 class MessageCaptureScreen : public MessageBase { 2449 SurfaceFlinger* flinger; 2450 DisplayID dpy; 2451 sp<IMemoryHeap>* heap; 2452 uint32_t* w; 2453 uint32_t* h; 2454 PixelFormat* f; 2455 uint32_t sw; 2456 uint32_t sh; 2457 uint32_t minLayerZ; 2458 uint32_t maxLayerZ; 2459 status_t result; 2460 public: 2461 MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 2462 sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2463 uint32_t sw, uint32_t sh, 2464 uint32_t minLayerZ, uint32_t maxLayerZ) 2465 : flinger(flinger), dpy(dpy), 2466 heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2467 minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2468 result(PERMISSION_DENIED) 2469 { 2470 } 2471 status_t getResult() const { 2472 return result; 2473 } 2474 virtual bool handler() { 2475 Mutex::Autolock _l(flinger->mStateLock); 2476 2477 // if we have secure windows, never allow the screen capture 2478 if (flinger->mSecureFrameBuffer) 2479 return true; 2480 2481 result = flinger->captureScreenImplLocked(dpy, 2482 heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 2483 2484 return true; 2485 } 2486 }; 2487 2488 sp<MessageBase> msg = new MessageCaptureScreen(this, 2489 dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 2490 status_t res = postMessageSync(msg); 2491 if (res == NO_ERROR) { 2492 res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 2493 } 2494 return res; 2495} 2496 2497// --------------------------------------------------------------------------- 2498 2499sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2500{ 2501 sp<Layer> result; 2502 Mutex::Autolock _l(mStateLock); 2503 result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2504 return result; 2505} 2506 2507// --------------------------------------------------------------------------- 2508 2509Client::Client(const sp<SurfaceFlinger>& flinger) 2510 : mFlinger(flinger), mNameGenerator(1) 2511{ 2512} 2513 2514Client::~Client() 2515{ 2516 const size_t count = mLayers.size(); 2517 for (size_t i=0 ; i<count ; i++) { 2518 sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 2519 if (layer != 0) { 2520 mFlinger->removeLayer(layer); 2521 } 2522 } 2523} 2524 2525status_t Client::initCheck() const { 2526 return NO_ERROR; 2527} 2528 2529size_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2530{ 2531 Mutex::Autolock _l(mLock); 2532 size_t name = mNameGenerator++; 2533 mLayers.add(name, layer); 2534 return name; 2535} 2536 2537void Client::detachLayer(const LayerBaseClient* layer) 2538{ 2539 Mutex::Autolock _l(mLock); 2540 // we do a linear search here, because this doesn't happen often 2541 const size_t count = mLayers.size(); 2542 for (size_t i=0 ; i<count ; i++) { 2543 if (mLayers.valueAt(i) == layer) { 2544 mLayers.removeItemsAt(i, 1); 2545 break; 2546 } 2547 } 2548} 2549sp<LayerBaseClient> Client::getLayerUser(int32_t i) const 2550{ 2551 Mutex::Autolock _l(mLock); 2552 sp<LayerBaseClient> lbc; 2553 wp<LayerBaseClient> layer(mLayers.valueFor(i)); 2554 if (layer != 0) { 2555 lbc = layer.promote(); 2556 LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2557 } 2558 return lbc; 2559} 2560 2561 2562status_t Client::onTransact( 2563 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2564{ 2565 // these must be checked 2566 IPCThreadState* ipc = IPCThreadState::self(); 2567 const int pid = ipc->getCallingPid(); 2568 const int uid = ipc->getCallingUid(); 2569 const int self_pid = getpid(); 2570 if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2571 // we're called from a different process, do the real check 2572 if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2573 { 2574 LOGE("Permission Denial: " 2575 "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2576 return PERMISSION_DENIED; 2577 } 2578 } 2579 return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2580} 2581 2582 2583sp<ISurface> Client::createSurface( 2584 ISurfaceComposerClient::surface_data_t* params, 2585 const String8& name, 2586 DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2587 uint32_t flags) 2588{ 2589 /* 2590 * createSurface must be called from the GL thread so that it can 2591 * have access to the GL context. 2592 */ 2593 2594 class MessageCreateSurface : public MessageBase { 2595 sp<ISurface> result; 2596 SurfaceFlinger* flinger; 2597 ISurfaceComposerClient::surface_data_t* params; 2598 Client* client; 2599 const String8& name; 2600 DisplayID display; 2601 uint32_t w, h; 2602 PixelFormat format; 2603 uint32_t flags; 2604 public: 2605 MessageCreateSurface(SurfaceFlinger* flinger, 2606 ISurfaceComposerClient::surface_data_t* params, 2607 const String8& name, Client* client, 2608 DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2609 uint32_t flags) 2610 : flinger(flinger), params(params), client(client), name(name), 2611 display(display), w(w), h(h), format(format), flags(flags) 2612 { 2613 } 2614 sp<ISurface> getResult() const { return result; } 2615 virtual bool handler() { 2616 result = flinger->createSurface(params, name, client, 2617 display, w, h, format, flags); 2618 return true; 2619 } 2620 }; 2621 2622 sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2623 params, name, this, display, w, h, format, flags); 2624 mFlinger->postMessageSync(msg); 2625 return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2626} 2627status_t Client::destroySurface(SurfaceID sid) { 2628 return mFlinger->removeSurface(this, sid); 2629} 2630 2631// --------------------------------------------------------------------------- 2632 2633GraphicBufferAlloc::GraphicBufferAlloc() {} 2634 2635GraphicBufferAlloc::~GraphicBufferAlloc() {} 2636 2637sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2638 PixelFormat format, uint32_t usage, status_t* error) { 2639 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 2640 status_t err = graphicBuffer->initCheck(); 2641 *error = err; 2642 if (err != 0 || graphicBuffer->handle == 0) { 2643 if (err == NO_MEMORY) { 2644 GraphicBuffer::dumpAllocationsToSystemLog(); 2645 } 2646 LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2647 "failed (%s), handle=%p", 2648 w, h, strerror(-err), graphicBuffer->handle); 2649 return 0; 2650 } 2651 return graphicBuffer; 2652} 2653 2654// --------------------------------------------------------------------------- 2655 2656GraphicPlane::GraphicPlane() 2657 : mHw(0) 2658{ 2659} 2660 2661GraphicPlane::~GraphicPlane() { 2662 delete mHw; 2663} 2664 2665bool GraphicPlane::initialized() const { 2666 return mHw ? true : false; 2667} 2668 2669int GraphicPlane::getWidth() const { 2670 return mWidth; 2671} 2672 2673int GraphicPlane::getHeight() const { 2674 return mHeight; 2675} 2676 2677void GraphicPlane::setDisplayHardware(DisplayHardware *hw) 2678{ 2679 mHw = hw; 2680 2681 // initialize the display orientation transform. 2682 // it's a constant that should come from the display driver. 2683 int displayOrientation = ISurfaceComposer::eOrientationDefault; 2684 char property[PROPERTY_VALUE_MAX]; 2685 if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 2686 //displayOrientation 2687 switch (atoi(property)) { 2688 case 90: 2689 displayOrientation = ISurfaceComposer::eOrientation90; 2690 break; 2691 case 270: 2692 displayOrientation = ISurfaceComposer::eOrientation270; 2693 break; 2694 } 2695 } 2696 2697 const float w = hw->getWidth(); 2698 const float h = hw->getHeight(); 2699 GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 2700 &mDisplayTransform); 2701 if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 2702 mDisplayWidth = h; 2703 mDisplayHeight = w; 2704 } else { 2705 mDisplayWidth = w; 2706 mDisplayHeight = h; 2707 } 2708 2709 setOrientation(ISurfaceComposer::eOrientationDefault); 2710} 2711 2712status_t GraphicPlane::orientationToTransfrom( 2713 int orientation, int w, int h, Transform* tr) 2714{ 2715 uint32_t flags = 0; 2716 switch (orientation) { 2717 case ISurfaceComposer::eOrientationDefault: 2718 flags = Transform::ROT_0; 2719 break; 2720 case ISurfaceComposer::eOrientation90: 2721 flags = Transform::ROT_90; 2722 break; 2723 case ISurfaceComposer::eOrientation180: 2724 flags = Transform::ROT_180; 2725 break; 2726 case ISurfaceComposer::eOrientation270: 2727 flags = Transform::ROT_270; 2728 break; 2729 default: 2730 return BAD_VALUE; 2731 } 2732 tr->set(flags, w, h); 2733 return NO_ERROR; 2734} 2735 2736status_t GraphicPlane::setOrientation(int orientation) 2737{ 2738 // If the rotation can be handled in hardware, this is where 2739 // the magic should happen. 2740 2741 const DisplayHardware& hw(displayHardware()); 2742 const float w = mDisplayWidth; 2743 const float h = mDisplayHeight; 2744 mWidth = int(w); 2745 mHeight = int(h); 2746 2747 Transform orientationTransform; 2748 GraphicPlane::orientationToTransfrom(orientation, w, h, 2749 &orientationTransform); 2750 if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2751 mWidth = int(h); 2752 mHeight = int(w); 2753 } 2754 2755 mOrientation = orientation; 2756 mGlobalTransform = mDisplayTransform * orientationTransform; 2757 return NO_ERROR; 2758} 2759 2760const DisplayHardware& GraphicPlane::displayHardware() const { 2761 return *mHw; 2762} 2763 2764DisplayHardware& GraphicPlane::editDisplayHardware() { 2765 return *mHw; 2766} 2767 2768const Transform& GraphicPlane::transform() const { 2769 return mGlobalTransform; 2770} 2771 2772EGLDisplay GraphicPlane::getEGLDisplay() const { 2773 return mHw->getEGLDisplay(); 2774} 2775 2776// --------------------------------------------------------------------------- 2777 2778}; // namespace android 2779