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