SurfaceFlinger.cpp revision e33a35f02576b482a5ac4891a78f6e72fb4c0dea
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2007 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdlib.h>
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h>
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdint.h>
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <unistd.h>
21776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski#include <fcntl.h>
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h>
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <math.h>
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <limits.h>
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/types.h>
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/stat.h>
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/ioctl.h>
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <cutils/log.h>
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <cutils/properties.h>
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <binder/IPCThreadState.h>
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <binder/IServiceManager.h>
3488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath#include <binder/MemoryHeapBase.h>
3588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath
3688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath#include <utils/String8.h>
3788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath#include <utils/String16.h>
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/StopWatch.h>
3988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <ui/GraphicBufferAllocator.h>
4188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath#include <ui/GraphicLog.h>
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <ui/PixelFormat.h>
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <pixelflinger/pixelflinger.h>
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <GLES/gl.h>
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "clz.h"
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "GLExtensions.h"
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Layer.h"
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "LayerBlur.h"
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "LayerBuffer.h"
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "LayerDim.h"
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "SurfaceFlinger.h"
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "DisplayHardware/DisplayHardware.h"
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "DisplayHardware/HWComposer.h"
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* ideally AID_GRAPHICS would be in a semi-public header
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * or there would be a way to map a user/group name to its id
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef AID_GRAPHICS
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define AID_GRAPHICS 1003
63776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski#endif
64776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define DISPLAY_COUNT       1
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskinamespace android {
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ---------------------------------------------------------------------------
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSurfaceFlinger::SurfaceFlinger()
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    :   BnSurfaceComposer(), Thread(false),
7288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath        mTransactionFlags(0),
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTransactionCount(0),
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mResizeTransationPending(false),
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLayersRemoved(false),
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mBootTime(systemTime()),
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mHardwareTest("android.permission.HARDWARE_TEST"),
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
8088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath        mDump("android.permission.DUMP"),
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVisibleRegionsDirty(false),
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mHwWorkListDirty(false),
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDeferReleaseConsole(false),
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mFreezeDisplay(false),
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mElectronBeamAnimation(false),
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mFreezeCount(0),
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mFreezeDisplayTime(0),
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDebugRegion(0),
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDebugBackground(0),
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDebugDisableHWC(0),
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDebugInSwapBuffers(0),
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLastSwapBufferTime(0),
9388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath        mDebugInTransaction(0),
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLastTransactionTime(0),
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mBootFinished(false),
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mConsoleSignals(0),
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSecureFrameBuffer(0)
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    init();
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::init()
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGI("SurfaceFlinger is starting");
10588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // debugging stuff...
10788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    char value[PROPERTY_VALUE_MAX];
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    property_get("debug.sf.showupdates", value, "0");
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mDebugRegion = atoi(value);
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    property_get("debug.sf.showbackground", value, "0");
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mDebugBackground = atoi(value);
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGI_IF(mDebugRegion,       "showupdates enabled");
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGI_IF(mDebugBackground,   "showbackground enabled");
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSurfaceFlinger::~SurfaceFlinger()
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glDeleteTextures(1, &mWormholeTexName);
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskioverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
12488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    return graphicPlane(0).displayHardware().getOverlayEngine();
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<IMemoryHeap> SurfaceFlinger::getCblk() const
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return mServerHeap;
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<ISurfaceComposerClient> bclient;
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<Client> client(new Client(this));
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = client->initCheck();
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err == NO_ERROR) {
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bclient = client;
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return bclient;
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<ISurfaceComposerClient> bclient;
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<UserClient> client(new UserClient(this));
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = client->initCheck();
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err == NO_ERROR) {
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bclient = client;
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
15188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    return bclient;
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const GraphicPlane& plane(mGraphicPlanes[dpy]);
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return plane;
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return const_cast<GraphicPlane&>(
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::bootFinished()
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const nsecs_t now = systemTime();
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const nsecs_t duration = now - mBootTime;
172776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
173776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski    mBootFinished = true;
174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    property_set("ctl.stop", "bootanim");
175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::onFirstRef()
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Wait for the main thread to be done with its initialization
182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mReadyToRunBarrier.wait();
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic inline uint16_t pack565(int r, int g, int b) {
186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return (r<<11)|(g<<5)|b;
187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t SurfaceFlinger::readyToRun()
190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGI(   "SurfaceFlinger's main thread ready to run. "
192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            "Initializing graphics H/W...");
193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // we only support one display currently
19588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    int dpy = 0;
196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // initialize the main display
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        GraphicPlane& plane(graphicPlane(dpy));
200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        DisplayHardware* const hw = new DisplayHardware(this, dpy);
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        plane.setDisplayHardware(hw);
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // create the shared control-block
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mServerHeap = new MemoryHeapBase(4096,
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    new(mServerCblk) surface_flinger_cblk_t;
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // initialize primary screen
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // (other display should be initialized in the same manner, but
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // asynchronously, as they could come and go. None of this is supported
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // yet).
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const GraphicPlane& plane(graphicPlane(dpy));
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const DisplayHardware& hw = plane.displayHardware();
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint32_t w = hw.getWidth();
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint32_t h = hw.getHeight();
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint32_t f = hw.getFormat();
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    hw.makeCurrent();
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // initialize the shared control block
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mServerCblk->connected |= 1<<dpy;
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    display_cblk_t* dcblk = mServerCblk->displays + dpy;
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    memset(dcblk, 0, sizeof(display_cblk_t));
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->w            = plane.getWidth();
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->h            = plane.getHeight();
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->format       = f;
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->xdpi         = hw.getDpiX();
23488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    dcblk->ydpi         = hw.getDpiY();
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->fps          = hw.getRefreshRate();
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dcblk->density      = hw.getDensity();
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Initialize OpenGL|ES
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glPixelStorei(GL_PACK_ALIGNMENT, 4);
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glEnableClientState(GL_VERTEX_ARRAY);
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glEnable(GL_SCISSOR_TEST);
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glShadeModel(GL_FLAT);
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glDisable(GL_DITHER);
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glDisable(GL_CULL_FACE);
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint16_t g1 = pack565(0x17,0x2f,0x17);
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const uint16_t textureData[4] = { g0, g1, g1, g0 };
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glGenTextures(1, &mWormholeTexName);
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glViewport(0, 0, w, h);
260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glMatrixMode(GL_PROJECTION);
261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glLoadIdentity();
262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    glOrthof(0, w, h, 0, 0, 1);
263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski   LayerDim::initDimmer(this, w, h);
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mReadyToRunBarrier.open();
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *  We're now ready to accept clients...
270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // start boot animation
273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    property_set("ctl.start", "bootanim");
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return NO_ERROR;
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ----------------------------------------------------------------------------
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#pragma mark -
28188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath#pragma mark Events Handler
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::waitForEvent()
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (true) {
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        nsecs_t timeout = -1;
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (UNLIKELY(isFrozen())) {
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // wait 5 seconds
291776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            const nsecs_t now = systemTime();
292776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            if (mFreezeDisplayTime == 0) {
293776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski                mFreezeDisplayTime = now;
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            timeout = waitTime>0 ? waitTime : 0;
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // see if we timed out
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (isFrozen()) {
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            const nsecs_t now = systemTime();
304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            nsecs_t frozenTime = (now - mFreezeDisplayTime);
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (frozenTime >= freezeDisplayTimeout) {
30688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath                // we timed out and are still frozen
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        mFreezeDisplay, mFreezeCount);
309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mFreezeDisplayTime = 0;
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mFreezeCount = 0;
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mFreezeDisplay = false;
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (msg != 0) {
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            switch (msg->what) {
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                case MessageQueue::INVALIDATE:
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // invalidate message, just return to the main loop
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return;
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::signalEvent() {
32688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    mEventQueue.invalidate();
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid SurfaceFlinger::signal() const {
330    // this is the IPC call
331    const_cast<SurfaceFlinger*>(this)->signalEvent();
332}
333
334status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
335        nsecs_t reltime, uint32_t flags)
336{
337    return mEventQueue.postMessage(msg, reltime, flags);
338}
339
340status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
341        nsecs_t reltime, uint32_t flags)
342{
343    status_t res = mEventQueue.postMessage(msg, reltime, flags);
344    if (res == NO_ERROR) {
345        msg->wait();
346    }
347    return res;
348}
349
350// ----------------------------------------------------------------------------
351#if 0
352#pragma mark -
353#pragma mark Main loop
354#endif
355
356bool SurfaceFlinger::threadLoop()
357{
358    waitForEvent();
359
360    // check for transactions
361    if (UNLIKELY(mConsoleSignals)) {
362        handleConsoleEvents();
363    }
364
365    if (LIKELY(mTransactionCount == 0)) {
366        // if we're in a global transaction, don't do anything.
367        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
368        uint32_t transactionFlags = getTransactionFlags(mask);
369        if (LIKELY(transactionFlags)) {
370            handleTransaction(transactionFlags);
371        }
372    }
373
374    // post surfaces (if needed)
375    handlePageFlip();
376
377    if (UNLIKELY(mHwWorkListDirty)) {
378        // build the h/w work list
379        handleWorkList();
380    }
381
382    const DisplayHardware& hw(graphicPlane(0).displayHardware());
383    if (LIKELY(hw.canDraw() && !isFrozen())) {
384        // repaint the framebuffer (if needed)
385
386        const int index = hw.getCurrentBufferIndex();
387        GraphicLog& logger(GraphicLog::getInstance());
388
389        logger.log(GraphicLog::SF_REPAINT, index);
390        handleRepaint();
391
392        // inform the h/w that we're done compositing
393        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
394        hw.compositionComplete();
395
396        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
397        postFramebuffer();
398
399        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
400        unlockClients();
401
402        logger.log(GraphicLog::SF_REPAINT_DONE, index);
403    } else {
404        // pretend we did the post
405        unlockClients();
406        usleep(16667); // 60 fps period
407    }
408    return true;
409}
410
411void SurfaceFlinger::postFramebuffer()
412{
413    if (!mInvalidRegion.isEmpty()) {
414        const DisplayHardware& hw(graphicPlane(0).displayHardware());
415        const nsecs_t now = systemTime();
416        mDebugInSwapBuffers = now;
417        hw.flip(mInvalidRegion);
418        mLastSwapBufferTime = systemTime() - now;
419        mDebugInSwapBuffers = 0;
420        mInvalidRegion.clear();
421    }
422}
423
424void SurfaceFlinger::handleConsoleEvents()
425{
426    // something to do with the console
427    const DisplayHardware& hw = graphicPlane(0).displayHardware();
428
429    int what = android_atomic_and(0, &mConsoleSignals);
430    if (what & eConsoleAcquired) {
431        hw.acquireScreen();
432        // this is a temporary work-around, eventually this should be called
433        // by the power-manager
434        if (mElectronBeamAnimation)
435            SurfaceFlinger::turnElectronBeamOn(0);
436    }
437
438    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
439        // We got the release signal before the acquire signal
440        mDeferReleaseConsole = false;
441        hw.releaseScreen();
442    }
443
444    if (what & eConsoleReleased) {
445        if (hw.isScreenAcquired()) {
446            hw.releaseScreen();
447        } else {
448            mDeferReleaseConsole = true;
449        }
450    }
451
452    mDirtyRegion.set(hw.bounds());
453}
454
455void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
456{
457    Vector< sp<LayerBase> > ditchedLayers;
458
459    /*
460     * Perform and commit the transaction
461     */
462
463    { // scope for the lock
464        Mutex::Autolock _l(mStateLock);
465        const nsecs_t now = systemTime();
466        mDebugInTransaction = now;
467        handleTransactionLocked(transactionFlags, ditchedLayers);
468        mLastTransactionTime = systemTime() - now;
469        mDebugInTransaction = 0;
470        mHwWorkListDirty = true;
471        // here the transaction has been committed
472    }
473
474    /*
475     * Clean-up all layers that went away
476     * (do this without the lock held)
477     */
478
479    const size_t count = ditchedLayers.size();
480    for (size_t i=0 ; i<count ; i++) {
481        if (ditchedLayers[i] != 0) {
482            //LOGD("ditching layer %p", ditchedLayers[i].get());
483            ditchedLayers[i]->ditch();
484        }
485    }
486}
487
488void SurfaceFlinger::handleTransactionLocked(
489        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
490{
491    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
492    const size_t count = currentLayers.size();
493
494    /*
495     * Traversal of the children
496     * (perform the transaction for each of them if needed)
497     */
498
499    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
500    if (layersNeedTransaction) {
501        for (size_t i=0 ; i<count ; i++) {
502            const sp<LayerBase>& layer = currentLayers[i];
503            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
504            if (!trFlags) continue;
505
506            const uint32_t flags = layer->doTransaction(0);
507            if (flags & Layer::eVisibleRegion)
508                mVisibleRegionsDirty = true;
509        }
510    }
511
512    /*
513     * Perform our own transaction if needed
514     */
515
516    if (transactionFlags & eTransactionNeeded) {
517        if (mCurrentState.orientation != mDrawingState.orientation) {
518            // the orientation has changed, recompute all visible regions
519            // and invalidate everything.
520
521            const int dpy = 0;
522            const int orientation = mCurrentState.orientation;
523            const uint32_t type = mCurrentState.orientationType;
524            GraphicPlane& plane(graphicPlane(dpy));
525            plane.setOrientation(orientation);
526
527            // update the shared control block
528            const DisplayHardware& hw(plane.displayHardware());
529            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
530            dcblk->orientation = orientation;
531            dcblk->w = plane.getWidth();
532            dcblk->h = plane.getHeight();
533
534            mVisibleRegionsDirty = true;
535            mDirtyRegion.set(hw.bounds());
536        }
537
538        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
539            // freezing or unfreezing the display -> trigger animation if needed
540            mFreezeDisplay = mCurrentState.freezeDisplay;
541            if (mFreezeDisplay)
542                 mFreezeDisplayTime = 0;
543        }
544
545        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
546            // layers have been added
547            mVisibleRegionsDirty = true;
548        }
549
550        // some layers might have been removed, so
551        // we need to update the regions they're exposing.
552        if (mLayersRemoved) {
553            mLayersRemoved = false;
554            mVisibleRegionsDirty = true;
555            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
556            const size_t count = previousLayers.size();
557            for (size_t i=0 ; i<count ; i++) {
558                const sp<LayerBase>& layer(previousLayers[i]);
559                if (currentLayers.indexOf( layer ) < 0) {
560                    // this layer is not visible anymore
561                    ditchedLayers.add(layer);
562                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
563                }
564            }
565        }
566    }
567
568    commitTransaction();
569}
570
571sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
572{
573    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
574}
575
576void SurfaceFlinger::computeVisibleRegions(
577    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
578{
579    const GraphicPlane& plane(graphicPlane(0));
580    const Transform& planeTransform(plane.transform());
581    const DisplayHardware& hw(plane.displayHardware());
582    const Region screenRegion(hw.bounds());
583
584    Region aboveOpaqueLayers;
585    Region aboveCoveredLayers;
586    Region dirty;
587
588    bool secureFrameBuffer = false;
589
590    size_t i = currentLayers.size();
591    while (i--) {
592        const sp<LayerBase>& layer = currentLayers[i];
593        layer->validateVisibility(planeTransform);
594
595        // start with the whole surface at its current location
596        const Layer::State& s(layer->drawingState());
597
598        /*
599         * opaqueRegion: area of a surface that is fully opaque.
600         */
601        Region opaqueRegion;
602
603        /*
604         * visibleRegion: area of a surface that is visible on screen
605         * and not fully transparent. This is essentially the layer's
606         * footprint minus the opaque regions above it.
607         * Areas covered by a translucent surface are considered visible.
608         */
609        Region visibleRegion;
610
611        /*
612         * coveredRegion: area of a surface that is covered by all
613         * visible regions above it (which includes the translucent areas).
614         */
615        Region coveredRegion;
616
617
618        // handle hidden surfaces by setting the visible region to empty
619        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
620            const bool translucent = layer->needsBlending();
621            const Rect bounds(layer->visibleBounds());
622            visibleRegion.set(bounds);
623            visibleRegion.andSelf(screenRegion);
624            if (!visibleRegion.isEmpty()) {
625                // Remove the transparent area from the visible region
626                if (translucent) {
627                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
628                }
629
630                // compute the opaque region
631                const int32_t layerOrientation = layer->getOrientation();
632                if (s.alpha==255 && !translucent &&
633                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
634                    // the opaque region is the layer's footprint
635                    opaqueRegion = visibleRegion;
636                }
637            }
638        }
639
640        // Clip the covered region to the visible region
641        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
642
643        // Update aboveCoveredLayers for next (lower) layer
644        aboveCoveredLayers.orSelf(visibleRegion);
645
646        // subtract the opaque region covered by the layers above us
647        visibleRegion.subtractSelf(aboveOpaqueLayers);
648
649        // compute this layer's dirty region
650        if (layer->contentDirty) {
651            // we need to invalidate the whole region
652            dirty = visibleRegion;
653            // as well, as the old visible region
654            dirty.orSelf(layer->visibleRegionScreen);
655            layer->contentDirty = false;
656        } else {
657            /* compute the exposed region:
658             *   the exposed region consists of two components:
659             *   1) what's VISIBLE now and was COVERED before
660             *   2) what's EXPOSED now less what was EXPOSED before
661             *
662             * note that (1) is conservative, we start with the whole
663             * visible region but only keep what used to be covered by
664             * something -- which mean it may have been exposed.
665             *
666             * (2) handles areas that were not covered by anything but got
667             * exposed because of a resize.
668             */
669            const Region newExposed = visibleRegion - coveredRegion;
670            const Region oldVisibleRegion = layer->visibleRegionScreen;
671            const Region oldCoveredRegion = layer->coveredRegionScreen;
672            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
673            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
674        }
675        dirty.subtractSelf(aboveOpaqueLayers);
676
677        // accumulate to the screen dirty region
678        dirtyRegion.orSelf(dirty);
679
680        // Update aboveOpaqueLayers for next (lower) layer
681        aboveOpaqueLayers.orSelf(opaqueRegion);
682
683        // Store the visible region is screen space
684        layer->setVisibleRegion(visibleRegion);
685        layer->setCoveredRegion(coveredRegion);
686
687        // If a secure layer is partially visible, lock-down the screen!
688        if (layer->isSecure() && !visibleRegion.isEmpty()) {
689            secureFrameBuffer = true;
690        }
691    }
692
693    // invalidate the areas where a layer was removed
694    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
695    mDirtyRegionRemovedLayer.clear();
696
697    mSecureFrameBuffer = secureFrameBuffer;
698    opaqueRegion = aboveOpaqueLayers;
699}
700
701
702void SurfaceFlinger::commitTransaction()
703{
704    mDrawingState = mCurrentState;
705    mResizeTransationPending = false;
706    mTransactionCV.broadcast();
707}
708
709void SurfaceFlinger::handlePageFlip()
710{
711    bool visibleRegions = mVisibleRegionsDirty;
712    LayerVector& currentLayers(
713            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
714    visibleRegions |= lockPageFlip(currentLayers);
715
716        const DisplayHardware& hw = graphicPlane(0).displayHardware();
717        const Region screenRegion(hw.bounds());
718        if (visibleRegions) {
719            Region opaqueRegion;
720            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
721
722            /*
723             *  rebuild the visible layer list
724             */
725            mVisibleLayersSortedByZ.clear();
726            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
727            size_t count = currentLayers.size();
728            mVisibleLayersSortedByZ.setCapacity(count);
729            for (size_t i=0 ; i<count ; i++) {
730                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
731                    mVisibleLayersSortedByZ.add(currentLayers[i]);
732            }
733
734            mWormholeRegion = screenRegion.subtract(opaqueRegion);
735            mVisibleRegionsDirty = false;
736            mHwWorkListDirty = true;
737        }
738
739    unlockPageFlip(currentLayers);
740    mDirtyRegion.andSelf(screenRegion);
741}
742
743bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
744{
745    bool recomputeVisibleRegions = false;
746    size_t count = currentLayers.size();
747    sp<LayerBase> const* layers = currentLayers.array();
748    for (size_t i=0 ; i<count ; i++) {
749        const sp<LayerBase>& layer(layers[i]);
750        layer->lockPageFlip(recomputeVisibleRegions);
751    }
752    return recomputeVisibleRegions;
753}
754
755void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
756{
757    const GraphicPlane& plane(graphicPlane(0));
758    const Transform& planeTransform(plane.transform());
759    size_t count = currentLayers.size();
760    sp<LayerBase> const* layers = currentLayers.array();
761    for (size_t i=0 ; i<count ; i++) {
762        const sp<LayerBase>& layer(layers[i]);
763        layer->unlockPageFlip(planeTransform, mDirtyRegion);
764    }
765}
766
767void SurfaceFlinger::handleWorkList()
768{
769    mHwWorkListDirty = false;
770    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
771    if (hwc.initCheck() == NO_ERROR) {
772        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
773        const size_t count = currentLayers.size();
774        hwc.createWorkList(count);
775        hwc_layer_t* const cur(hwc.getLayers());
776        for (size_t i=0 ; cur && i<count ; i++) {
777            currentLayers[i]->setGeometry(&cur[i]);
778            if (mDebugDisableHWC) {
779                cur[i].compositionType = HWC_FRAMEBUFFER;
780                cur[i].flags |= HWC_SKIP_LAYER;
781            }
782        }
783    }
784}
785
786void SurfaceFlinger::handleRepaint()
787{
788    // compute the invalid region
789    mInvalidRegion.orSelf(mDirtyRegion);
790    if (mInvalidRegion.isEmpty()) {
791        // nothing to do
792        return;
793    }
794
795    if (UNLIKELY(mDebugRegion)) {
796        debugFlashRegions();
797    }
798
799    // set the frame buffer
800    const DisplayHardware& hw(graphicPlane(0).displayHardware());
801    glMatrixMode(GL_MODELVIEW);
802    glLoadIdentity();
803
804    uint32_t flags = hw.getFlags();
805    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
806        (flags & DisplayHardware::BUFFER_PRESERVED))
807    {
808        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
809        // takes a rectangle, we must make sure to update that whole
810        // rectangle in that case
811        if (flags & DisplayHardware::SWAP_RECTANGLE) {
812            // TODO: we really should be able to pass a region to
813            // SWAP_RECTANGLE so that we don't have to redraw all this.
814            mDirtyRegion.set(mInvalidRegion.bounds());
815        } else {
816            // in the BUFFER_PRESERVED case, obviously, we can update only
817            // what's needed and nothing more.
818            // NOTE: this is NOT a common case, as preserving the backbuffer
819            // is costly and usually involves copying the whole update back.
820        }
821    } else {
822        if (flags & DisplayHardware::PARTIAL_UPDATES) {
823            // We need to redraw the rectangle that will be updated
824            // (pushed to the framebuffer).
825            // This is needed because PARTIAL_UPDATES only takes one
826            // rectangle instead of a region (see DisplayHardware::flip())
827            mDirtyRegion.set(mInvalidRegion.bounds());
828        } else {
829            // we need to redraw everything (the whole screen)
830            mDirtyRegion.set(hw.bounds());
831            mInvalidRegion = mDirtyRegion;
832        }
833    }
834
835    // compose all surfaces
836    composeSurfaces(mDirtyRegion);
837
838    // clear the dirty regions
839    mDirtyRegion.clear();
840}
841
842void SurfaceFlinger::composeSurfaces(const Region& dirty)
843{
844    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
845        // should never happen unless the window manager has a bug
846        // draw something...
847        drawWormhole();
848    }
849
850    status_t err = NO_ERROR;
851    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
852    size_t count = layers.size();
853
854    const DisplayHardware& hw(graphicPlane(0).displayHardware());
855    HWComposer& hwc(hw.getHwComposer());
856    hwc_layer_t* const cur(hwc.getLayers());
857
858    LOGE_IF(cur && hwc.getNumLayers() != count,
859            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
860            hwc.getNumLayers(), count);
861
862    // just to be extra-safe, use the smallest count
863    if (hwc.initCheck() == NO_ERROR) {
864        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
865    }
866
867    /*
868     *  update the per-frame h/w composer data for each layer
869     *  and build the transparent region of the FB
870     */
871    Region transparent;
872    if (cur) {
873        for (size_t i=0 ; i<count ; i++) {
874            const sp<LayerBase>& layer(layers[i]);
875            layer->setPerFrameData(&cur[i]);
876            if (cur[i].hints & HWC_HINT_CLEAR_FB) {
877                if (!(layer->needsBlending())) {
878                    transparent.orSelf(layer->visibleRegionScreen);
879                }
880            }
881        }
882        err = hwc.prepare();
883        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
884    }
885
886    /*
887     *  clear the area of the FB that need to be transparent
888     */
889    transparent.andSelf(dirty);
890    if (!transparent.isEmpty()) {
891        glClearColor(0,0,0,0);
892        Region::const_iterator it = transparent.begin();
893        Region::const_iterator const end = transparent.end();
894        const int32_t height = hw.getHeight();
895        while (it != end) {
896            const Rect& r(*it++);
897            const GLint sy = height - (r.top + r.height());
898            glScissor(r.left, sy, r.width(), r.height());
899            glClear(GL_COLOR_BUFFER_BIT);
900        }
901    }
902
903
904    /*
905     * and then, render the layers targeted at the framebuffer
906     */
907    for (size_t i=0 ; i<count ; i++) {
908        if (cur) {
909            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
910                !(cur[i].flags & HWC_SKIP_LAYER)) {
911                // skip layers handled by the HAL
912                continue;
913            }
914        }
915
916        const sp<LayerBase>& layer(layers[i]);
917        const Region clip(dirty.intersect(layer->visibleRegionScreen));
918        if (!clip.isEmpty()) {
919            layer->draw(clip);
920        }
921    }
922}
923
924void SurfaceFlinger::unlockClients()
925{
926    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
927    const size_t count = drawingLayers.size();
928    sp<LayerBase> const* const layers = drawingLayers.array();
929    for (size_t i=0 ; i<count ; ++i) {
930        const sp<LayerBase>& layer = layers[i];
931        layer->finishPageFlip();
932    }
933}
934
935void SurfaceFlinger::debugFlashRegions()
936{
937    const DisplayHardware& hw(graphicPlane(0).displayHardware());
938    const uint32_t flags = hw.getFlags();
939
940    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
941            (flags & DisplayHardware::BUFFER_PRESERVED))) {
942        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
943                mDirtyRegion.bounds() : hw.bounds());
944        composeSurfaces(repaint);
945    }
946
947    TextureManager::deactivateTextures();
948
949    glDisable(GL_BLEND);
950    glDisable(GL_DITHER);
951    glDisable(GL_SCISSOR_TEST);
952
953    static int toggle = 0;
954    toggle = 1 - toggle;
955    if (toggle) {
956        glColor4f(1, 0, 1, 1);
957    } else {
958        glColor4f(1, 1, 0, 1);
959    }
960
961    Region::const_iterator it = mDirtyRegion.begin();
962    Region::const_iterator const end = mDirtyRegion.end();
963    while (it != end) {
964        const Rect& r = *it++;
965        GLfloat vertices[][2] = {
966                { r.left,  r.top },
967                { r.left,  r.bottom },
968                { r.right, r.bottom },
969                { r.right, r.top }
970        };
971        glVertexPointer(2, GL_FLOAT, 0, vertices);
972        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
973    }
974
975    if (mInvalidRegion.isEmpty()) {
976        mDirtyRegion.dump("mDirtyRegion");
977        mInvalidRegion.dump("mInvalidRegion");
978    }
979    hw.flip(mInvalidRegion);
980
981    if (mDebugRegion > 1)
982        usleep(mDebugRegion * 1000);
983
984    glEnable(GL_SCISSOR_TEST);
985    //mDirtyRegion.dump("mDirtyRegion");
986}
987
988void SurfaceFlinger::drawWormhole() const
989{
990    const Region region(mWormholeRegion.intersect(mDirtyRegion));
991    if (region.isEmpty())
992        return;
993
994    const DisplayHardware& hw(graphicPlane(0).displayHardware());
995    const int32_t width = hw.getWidth();
996    const int32_t height = hw.getHeight();
997
998    glDisable(GL_BLEND);
999    glDisable(GL_DITHER);
1000
1001    if (LIKELY(!mDebugBackground)) {
1002        glClearColor(0,0,0,0);
1003        Region::const_iterator it = region.begin();
1004        Region::const_iterator const end = region.end();
1005        while (it != end) {
1006            const Rect& r = *it++;
1007            const GLint sy = height - (r.top + r.height());
1008            glScissor(r.left, sy, r.width(), r.height());
1009            glClear(GL_COLOR_BUFFER_BIT);
1010        }
1011    } else {
1012        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1013                { width, height }, { 0, height }  };
1014        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1015        glVertexPointer(2, GL_SHORT, 0, vertices);
1016        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1017        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1018#if defined(GL_OES_EGL_image_external)
1019        if (GLExtensions::getInstance().haveTextureExternal()) {
1020            glDisable(GL_TEXTURE_EXTERNAL_OES);
1021        }
1022#endif
1023        glEnable(GL_TEXTURE_2D);
1024        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1025        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1026        glMatrixMode(GL_TEXTURE);
1027        glLoadIdentity();
1028        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
1029        Region::const_iterator it = region.begin();
1030        Region::const_iterator const end = region.end();
1031        while (it != end) {
1032            const Rect& r = *it++;
1033            const GLint sy = height - (r.top + r.height());
1034            glScissor(r.left, sy, r.width(), r.height());
1035            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1036        }
1037        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1038    }
1039}
1040
1041void SurfaceFlinger::debugShowFPS() const
1042{
1043    static int mFrameCount;
1044    static int mLastFrameCount = 0;
1045    static nsecs_t mLastFpsTime = 0;
1046    static float mFps = 0;
1047    mFrameCount++;
1048    nsecs_t now = systemTime();
1049    nsecs_t diff = now - mLastFpsTime;
1050    if (diff > ms2ns(250)) {
1051        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1052        mLastFpsTime = now;
1053        mLastFrameCount = mFrameCount;
1054    }
1055    // XXX: mFPS has the value we want
1056 }
1057
1058status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1059{
1060    Mutex::Autolock _l(mStateLock);
1061    addLayer_l(layer);
1062    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1063    return NO_ERROR;
1064}
1065
1066status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1067{
1068    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
1069    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
1070}
1071
1072ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
1073        const sp<LayerBaseClient>& lbc)
1074{
1075    Mutex::Autolock _l(mStateLock);
1076
1077    // attach this layer to the client
1078    ssize_t name = client->attachLayer(lbc);
1079
1080    // add this layer to the current state list
1081    addLayer_l(lbc);
1082
1083    return name;
1084}
1085
1086status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
1087{
1088    Mutex::Autolock _l(mStateLock);
1089    status_t err = purgatorizeLayer_l(layer);
1090    if (err == NO_ERROR)
1091        setTransactionFlags(eTransactionNeeded);
1092    return err;
1093}
1094
1095status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1096{
1097    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1098    if (lbc != 0) {
1099        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1100    }
1101    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1102    if (index >= 0) {
1103        mLayersRemoved = true;
1104        return NO_ERROR;
1105    }
1106    return status_t(index);
1107}
1108
1109status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
1110{
1111    // remove the layer from the main list (through a transaction).
1112    ssize_t err = removeLayer_l(layerBase);
1113
1114    layerBase->onRemoved();
1115
1116    // it's possible that we don't find a layer, because it might
1117    // have been destroyed already -- this is not technically an error
1118    // from the user because there is a race between Client::destroySurface(),
1119    // ~Client() and ~ISurface().
1120    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
1121}
1122
1123status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1124{
1125    layer->forceVisibilityTransaction();
1126    setTransactionFlags(eTraversalNeeded);
1127    return NO_ERROR;
1128}
1129
1130uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1131{
1132    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1133}
1134
1135uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1136{
1137    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1138    if ((old & flags)==0) { // wake the server up
1139        signalEvent();
1140    }
1141    return old;
1142}
1143
1144void SurfaceFlinger::openGlobalTransaction()
1145{
1146    android_atomic_inc(&mTransactionCount);
1147}
1148
1149void SurfaceFlinger::closeGlobalTransaction()
1150{
1151    if (android_atomic_dec(&mTransactionCount) == 1) {
1152        signalEvent();
1153
1154        // if there is a transaction with a resize, wait for it to
1155        // take effect before returning.
1156        Mutex::Autolock _l(mStateLock);
1157        while (mResizeTransationPending) {
1158            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1159            if (CC_UNLIKELY(err != NO_ERROR)) {
1160                // just in case something goes wrong in SF, return to the
1161                // called after a few seconds.
1162                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1163                mResizeTransationPending = false;
1164                break;
1165            }
1166        }
1167    }
1168}
1169
1170status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1171{
1172    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1173        return BAD_VALUE;
1174
1175    Mutex::Autolock _l(mStateLock);
1176    mCurrentState.freezeDisplay = 1;
1177    setTransactionFlags(eTransactionNeeded);
1178
1179    // flags is intended to communicate some sort of animation behavior
1180    // (for instance fading)
1181    return NO_ERROR;
1182}
1183
1184status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1185{
1186    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1187        return BAD_VALUE;
1188
1189    Mutex::Autolock _l(mStateLock);
1190    mCurrentState.freezeDisplay = 0;
1191    setTransactionFlags(eTransactionNeeded);
1192
1193    // flags is intended to communicate some sort of animation behavior
1194    // (for instance fading)
1195    return NO_ERROR;
1196}
1197
1198int SurfaceFlinger::setOrientation(DisplayID dpy,
1199        int orientation, uint32_t flags)
1200{
1201    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1202        return BAD_VALUE;
1203
1204    Mutex::Autolock _l(mStateLock);
1205    if (mCurrentState.orientation != orientation) {
1206        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1207            mCurrentState.orientationType = flags;
1208            mCurrentState.orientation = orientation;
1209            setTransactionFlags(eTransactionNeeded);
1210            mTransactionCV.wait(mStateLock);
1211        } else {
1212            orientation = BAD_VALUE;
1213        }
1214    }
1215    return orientation;
1216}
1217
1218sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
1219        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1220        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1221        uint32_t flags)
1222{
1223    sp<LayerBaseClient> layer;
1224    sp<LayerBaseClient::Surface> surfaceHandle;
1225
1226    if (int32_t(w|h) < 0) {
1227        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
1228                int(w), int(h));
1229        return surfaceHandle;
1230    }
1231
1232    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1233    sp<Layer> normalLayer;
1234    switch (flags & eFXSurfaceMask) {
1235        case eFXSurfaceNormal:
1236#if HAS_PUSH_BUFFERS
1237            if (UNLIKELY(flags & ePushBuffers)) {
1238                layer = createPushBuffersSurface(client, d, w, h, flags);
1239            } else
1240#endif
1241            {
1242                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1243                layer = normalLayer;
1244            }
1245            break;
1246        case eFXSurfaceBlur:
1247            layer = createBlurSurface(client, d, w, h, flags);
1248            break;
1249        case eFXSurfaceDim:
1250            layer = createDimSurface(client, d, w, h, flags);
1251            break;
1252    }
1253
1254    if (layer != 0) {
1255        layer->initStates(w, h, flags);
1256        layer->setName(name);
1257        ssize_t token = addClientLayer(client, layer);
1258
1259        surfaceHandle = layer->getSurface();
1260        if (surfaceHandle != 0) {
1261            params->token = token;
1262            params->identity = surfaceHandle->getIdentity();
1263            params->width = w;
1264            params->height = h;
1265            params->format = format;
1266            if (normalLayer != 0) {
1267                Mutex::Autolock _l(mStateLock);
1268                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1269            }
1270        }
1271
1272        setTransactionFlags(eTransactionNeeded);
1273    }
1274
1275    return surfaceHandle;
1276}
1277
1278sp<Layer> SurfaceFlinger::createNormalSurface(
1279        const sp<Client>& client, DisplayID display,
1280        uint32_t w, uint32_t h, uint32_t flags,
1281        PixelFormat& format)
1282{
1283    // initialize the surfaces
1284    switch (format) { // TODO: take h/w into account
1285    case PIXEL_FORMAT_TRANSPARENT:
1286    case PIXEL_FORMAT_TRANSLUCENT:
1287        format = PIXEL_FORMAT_RGBA_8888;
1288        break;
1289    case PIXEL_FORMAT_OPAQUE:
1290#ifdef NO_RGBX_8888
1291        format = PIXEL_FORMAT_RGB_565;
1292#else
1293        format = PIXEL_FORMAT_RGBX_8888;
1294#endif
1295        break;
1296    }
1297
1298#ifdef NO_RGBX_8888
1299    if (format == PIXEL_FORMAT_RGBX_8888)
1300        format = PIXEL_FORMAT_RGBA_8888;
1301#endif
1302
1303    sp<Layer> layer = new Layer(this, display, client);
1304    status_t err = layer->setBuffers(w, h, format, flags);
1305    if (LIKELY(err != NO_ERROR)) {
1306        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1307        layer.clear();
1308    }
1309    return layer;
1310}
1311
1312sp<LayerBlur> SurfaceFlinger::createBlurSurface(
1313        const sp<Client>& client, DisplayID display,
1314        uint32_t w, uint32_t h, uint32_t flags)
1315{
1316    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1317    layer->initStates(w, h, flags);
1318    return layer;
1319}
1320
1321sp<LayerDim> SurfaceFlinger::createDimSurface(
1322        const sp<Client>& client, DisplayID display,
1323        uint32_t w, uint32_t h, uint32_t flags)
1324{
1325    sp<LayerDim> layer = new LayerDim(this, display, client);
1326    layer->initStates(w, h, flags);
1327    return layer;
1328}
1329
1330sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1331        const sp<Client>& client, DisplayID display,
1332        uint32_t w, uint32_t h, uint32_t flags)
1333{
1334    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1335    layer->initStates(w, h, flags);
1336    return layer;
1337}
1338
1339status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
1340{
1341    /*
1342     * called by the window manager, when a surface should be marked for
1343     * destruction.
1344     *
1345     * The surface is removed from the current and drawing lists, but placed
1346     * in the purgatory queue, so it's not destroyed right-away (we need
1347     * to wait for all client's references to go away first).
1348     */
1349
1350    status_t err = NAME_NOT_FOUND;
1351    Mutex::Autolock _l(mStateLock);
1352    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1353    if (layer != 0) {
1354        err = purgatorizeLayer_l(layer);
1355        if (err == NO_ERROR) {
1356            setTransactionFlags(eTransactionNeeded);
1357        }
1358    }
1359    return err;
1360}
1361
1362status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1363{
1364    // called by ~ISurface() when all references are gone
1365
1366    class MessageDestroySurface : public MessageBase {
1367        SurfaceFlinger* flinger;
1368        sp<LayerBaseClient> layer;
1369    public:
1370        MessageDestroySurface(
1371                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
1372            : flinger(flinger), layer(layer) { }
1373        virtual bool handler() {
1374            sp<LayerBaseClient> l(layer);
1375            layer.clear(); // clear it outside of the lock;
1376            Mutex::Autolock _l(flinger->mStateLock);
1377            /*
1378             * remove the layer from the current list -- chances are that it's
1379             * not in the list anyway, because it should have been removed
1380             * already upon request of the client (eg: window manager).
1381             * However, a buggy client could have not done that.
1382             * Since we know we don't have any more clients, we don't need
1383             * to use the purgatory.
1384             */
1385            status_t err = flinger->removeLayer_l(l);
1386            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1387                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1388            return true;
1389        }
1390    };
1391
1392    postMessageAsync( new MessageDestroySurface(this, layer) );
1393    return NO_ERROR;
1394}
1395
1396status_t SurfaceFlinger::setClientState(
1397        const sp<Client>& client,
1398        int32_t count,
1399        const layer_state_t* states)
1400{
1401    Mutex::Autolock _l(mStateLock);
1402    uint32_t flags = 0;
1403    for (int i=0 ; i<count ; i++) {
1404        const layer_state_t& s(states[i]);
1405        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1406        if (layer != 0) {
1407            const uint32_t what = s.what;
1408            if (what & ePositionChanged) {
1409                if (layer->setPosition(s.x, s.y))
1410                    flags |= eTraversalNeeded;
1411            }
1412            if (what & eLayerChanged) {
1413                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1414                if (layer->setLayer(s.z)) {
1415                    mCurrentState.layersSortedByZ.removeAt(idx);
1416                    mCurrentState.layersSortedByZ.add(layer);
1417                    // we need traversal (state changed)
1418                    // AND transaction (list changed)
1419                    flags |= eTransactionNeeded|eTraversalNeeded;
1420                }
1421            }
1422            if (what & eSizeChanged) {
1423                if (layer->setSize(s.w, s.h)) {
1424                    flags |= eTraversalNeeded;
1425                    mResizeTransationPending = true;
1426                }
1427            }
1428            if (what & eAlphaChanged) {
1429                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1430                    flags |= eTraversalNeeded;
1431            }
1432            if (what & eMatrixChanged) {
1433                if (layer->setMatrix(s.matrix))
1434                    flags |= eTraversalNeeded;
1435            }
1436            if (what & eTransparentRegionChanged) {
1437                if (layer->setTransparentRegionHint(s.transparentRegion))
1438                    flags |= eTraversalNeeded;
1439            }
1440            if (what & eVisibilityChanged) {
1441                if (layer->setFlags(s.flags, s.mask))
1442                    flags |= eTraversalNeeded;
1443            }
1444        }
1445    }
1446    if (flags) {
1447        setTransactionFlags(flags);
1448    }
1449    return NO_ERROR;
1450}
1451
1452void SurfaceFlinger::screenReleased(int dpy)
1453{
1454    // this may be called by a signal handler, we can't do too much in here
1455    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1456    signalEvent();
1457}
1458
1459void SurfaceFlinger::screenAcquired(int dpy)
1460{
1461    // this may be called by a signal handler, we can't do too much in here
1462    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1463    signalEvent();
1464}
1465
1466status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1467{
1468    const size_t SIZE = 1024;
1469    char buffer[SIZE];
1470    String8 result;
1471    if (!mDump.checkCalling()) {
1472        snprintf(buffer, SIZE, "Permission Denial: "
1473                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1474                IPCThreadState::self()->getCallingPid(),
1475                IPCThreadState::self()->getCallingUid());
1476        result.append(buffer);
1477    } else {
1478
1479        // figure out if we're stuck somewhere
1480        const nsecs_t now = systemTime();
1481        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
1482        const nsecs_t inTransaction(mDebugInTransaction);
1483        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
1484        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1485
1486        // Try to get the main lock, but don't insist if we can't
1487        // (this would indicate SF is stuck, but we want to be able to
1488        // print something in dumpsys).
1489        int retry = 3;
1490        while (mStateLock.tryLock()<0 && --retry>=0) {
1491            usleep(1000000);
1492        }
1493        const bool locked(retry >= 0);
1494        if (!locked) {
1495            snprintf(buffer, SIZE,
1496                    "SurfaceFlinger appears to be unresponsive, "
1497                    "dumping anyways (no locks held)\n");
1498            result.append(buffer);
1499        }
1500
1501        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1502        const size_t count = currentLayers.size();
1503        for (size_t i=0 ; i<count ; i++) {
1504            const sp<LayerBase>& layer(currentLayers[i]);
1505            layer->dump(result, buffer, SIZE);
1506            const Layer::State& s(layer->drawingState());
1507            s.transparentRegion.dump(result, "transparentRegion");
1508            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1509            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1510        }
1511
1512        mWormholeRegion.dump(result, "WormholeRegion");
1513        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1514        snprintf(buffer, SIZE,
1515                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1516                mFreezeDisplay?"yes":"no", mFreezeCount,
1517                mCurrentState.orientation, hw.canDraw());
1518        result.append(buffer);
1519        snprintf(buffer, SIZE,
1520                "  last eglSwapBuffers() time: %f us\n"
1521                "  last transaction time     : %f us\n",
1522                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
1523        result.append(buffer);
1524
1525        if (inSwapBuffersDuration || !locked) {
1526            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
1527                    inSwapBuffersDuration/1000.0);
1528            result.append(buffer);
1529        }
1530
1531        if (inTransactionDuration || !locked) {
1532            snprintf(buffer, SIZE, "  transaction time: %f us\n",
1533                    inTransactionDuration/1000.0);
1534            result.append(buffer);
1535        }
1536
1537        HWComposer& hwc(hw.getHwComposer());
1538        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
1539                hwc.initCheck()==NO_ERROR ? "present" : "not present",
1540                mDebugDisableHWC ? "disabled" : "enabled");
1541        result.append(buffer);
1542        hwc.dump(result, buffer, SIZE);
1543
1544        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1545        alloc.dump(result);
1546
1547        if (locked) {
1548            mStateLock.unlock();
1549        }
1550    }
1551    write(fd, result.string(), result.size());
1552    return NO_ERROR;
1553}
1554
1555status_t SurfaceFlinger::onTransact(
1556    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1557{
1558    switch (code) {
1559        case CREATE_CONNECTION:
1560        case OPEN_GLOBAL_TRANSACTION:
1561        case CLOSE_GLOBAL_TRANSACTION:
1562        case SET_ORIENTATION:
1563        case FREEZE_DISPLAY:
1564        case UNFREEZE_DISPLAY:
1565        case BOOT_FINISHED:
1566        case TURN_ELECTRON_BEAM_OFF:
1567        case TURN_ELECTRON_BEAM_ON:
1568        {
1569            // codes that require permission check
1570            IPCThreadState* ipc = IPCThreadState::self();
1571            const int pid = ipc->getCallingPid();
1572            const int uid = ipc->getCallingUid();
1573            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1574                LOGE("Permission Denial: "
1575                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1576                return PERMISSION_DENIED;
1577            }
1578            break;
1579        }
1580        case CAPTURE_SCREEN:
1581        {
1582            // codes that require permission check
1583            IPCThreadState* ipc = IPCThreadState::self();
1584            const int pid = ipc->getCallingPid();
1585            const int uid = ipc->getCallingUid();
1586            if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
1587                LOGE("Permission Denial: "
1588                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
1589                return PERMISSION_DENIED;
1590            }
1591            break;
1592        }
1593    }
1594
1595    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1596    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1597        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1598        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1599            IPCThreadState* ipc = IPCThreadState::self();
1600            const int pid = ipc->getCallingPid();
1601            const int uid = ipc->getCallingUid();
1602            LOGE("Permission Denial: "
1603                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1604            return PERMISSION_DENIED;
1605        }
1606        int n;
1607        switch (code) {
1608            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1609            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1610                return NO_ERROR;
1611            case 1002:  // SHOW_UPDATES
1612                n = data.readInt32();
1613                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1614                return NO_ERROR;
1615            case 1003:  // SHOW_BACKGROUND
1616                n = data.readInt32();
1617                mDebugBackground = n ? 1 : 0;
1618                return NO_ERROR;
1619            case 1008:  // toggle use of hw composer
1620                n = data.readInt32();
1621                mDebugDisableHWC = n ? 1 : 0;
1622                mHwWorkListDirty = true;
1623                // fall-through...
1624            case 1004:{ // repaint everything
1625                Mutex::Autolock _l(mStateLock);
1626                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1627                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1628                signalEvent();
1629                return NO_ERROR;
1630            }
1631            case 1005:{ // force transaction
1632                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1633                return NO_ERROR;
1634            }
1635            case 1006:{ // enable/disable GraphicLog
1636                int enabled = data.readInt32();
1637                GraphicLog::getInstance().setEnabled(enabled);
1638                return NO_ERROR;
1639            }
1640            case 1007: // set mFreezeCount
1641                mFreezeCount = data.readInt32();
1642                mFreezeDisplayTime = 0;
1643                return NO_ERROR;
1644            case 1010:  // interrogate.
1645                reply->writeInt32(0);
1646                reply->writeInt32(0);
1647                reply->writeInt32(mDebugRegion);
1648                reply->writeInt32(mDebugBackground);
1649                return NO_ERROR;
1650            case 1013: {
1651                Mutex::Autolock _l(mStateLock);
1652                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1653                reply->writeInt32(hw.getPageFlipCount());
1654            }
1655            return NO_ERROR;
1656        }
1657    }
1658    return err;
1659}
1660
1661// ---------------------------------------------------------------------------
1662
1663status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
1664        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
1665{
1666    if (!GLExtensions::getInstance().haveFramebufferObject())
1667        return INVALID_OPERATION;
1668
1669    // get screen geometry
1670    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
1671    const uint32_t hw_w = hw.getWidth();
1672    const uint32_t hw_h = hw.getHeight();
1673    GLfloat u = 1;
1674    GLfloat v = 1;
1675
1676    // make sure to clear all GL error flags
1677    while ( glGetError() != GL_NO_ERROR ) ;
1678
1679    // create a FBO
1680    GLuint name, tname;
1681    glGenTextures(1, &tname);
1682    glBindTexture(GL_TEXTURE_2D, tname);
1683    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1684            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1685    if (glGetError() != GL_NO_ERROR) {
1686        GLint tw = (2 << (31 - clz(hw_w)));
1687        GLint th = (2 << (31 - clz(hw_h)));
1688        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1689                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1690        u = GLfloat(hw_w) / tw;
1691        v = GLfloat(hw_h) / th;
1692    }
1693    glGenFramebuffersOES(1, &name);
1694    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
1695    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
1696            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
1697
1698    // redraw the screen entirely...
1699    glClearColor(0,0,0,1);
1700    glClear(GL_COLOR_BUFFER_BIT);
1701    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
1702    const size_t count = layers.size();
1703    for (size_t i=0 ; i<count ; ++i) {
1704        const sp<LayerBase>& layer(layers[i]);
1705        layer->drawForSreenShot();
1706    }
1707
1708    // back to main framebuffer
1709    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
1710    glDisable(GL_SCISSOR_TEST);
1711    glDeleteFramebuffersOES(1, &name);
1712
1713    *textureName = tname;
1714    *uOut = u;
1715    *vOut = v;
1716    return NO_ERROR;
1717}
1718
1719// ---------------------------------------------------------------------------
1720
1721status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
1722{
1723    status_t result = PERMISSION_DENIED;
1724
1725    if (!GLExtensions::getInstance().haveFramebufferObject())
1726        return INVALID_OPERATION;
1727
1728    // get screen geometry
1729    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1730    const uint32_t hw_w = hw.getWidth();
1731    const uint32_t hw_h = hw.getHeight();
1732    const Region screenBounds(hw.bounds());
1733
1734    GLfloat u, v;
1735    GLuint tname;
1736    result = renderScreenToTextureLocked(0, &tname, &u, &v);
1737    if (result != NO_ERROR) {
1738        return result;
1739    }
1740
1741    GLfloat vtx[8];
1742    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
1743    glEnable(GL_TEXTURE_2D);
1744    glBindTexture(GL_TEXTURE_2D, tname);
1745    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1746    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1747    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1748    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
1749    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1750    glVertexPointer(2, GL_FLOAT, 0, vtx);
1751
1752    class s_curve_interpolator {
1753        const float nbFrames, s, v;
1754    public:
1755        s_curve_interpolator(int nbFrames, float s)
1756        : nbFrames(1.0f / (nbFrames-1)), s(s),
1757          v(1.0f + expf(-s + 0.5f*s)) {
1758        }
1759        float operator()(int f) {
1760            const float x = f * nbFrames;
1761            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
1762        }
1763    };
1764
1765    class v_stretch {
1766        const GLfloat hw_w, hw_h;
1767    public:
1768        v_stretch(uint32_t hw_w, uint32_t hw_h)
1769        : hw_w(hw_w), hw_h(hw_h) {
1770        }
1771        void operator()(GLfloat* vtx, float v) {
1772            const GLfloat w = hw_w + (hw_w * v);
1773            const GLfloat h = hw_h - (hw_h * v);
1774            const GLfloat x = (hw_w - w) * 0.5f;
1775            const GLfloat y = (hw_h - h) * 0.5f;
1776            vtx[0] = x;         vtx[1] = y;
1777            vtx[2] = x;         vtx[3] = y + h;
1778            vtx[4] = x + w;     vtx[5] = y + h;
1779            vtx[6] = x + w;     vtx[7] = y;
1780        }
1781    };
1782
1783    class h_stretch {
1784        const GLfloat hw_w, hw_h;
1785    public:
1786        h_stretch(uint32_t hw_w, uint32_t hw_h)
1787        : hw_w(hw_w), hw_h(hw_h) {
1788        }
1789        void operator()(GLfloat* vtx, float v) {
1790            const GLfloat w = hw_w - (hw_w * v);
1791            const GLfloat h = 1.0f;
1792            const GLfloat x = (hw_w - w) * 0.5f;
1793            const GLfloat y = (hw_h - h) * 0.5f;
1794            vtx[0] = x;         vtx[1] = y;
1795            vtx[2] = x;         vtx[3] = y + h;
1796            vtx[4] = x + w;     vtx[5] = y + h;
1797            vtx[6] = x + w;     vtx[7] = y;
1798        }
1799    };
1800
1801    // the full animation is 24 frames
1802    const int nbFrames = 12;
1803    s_curve_interpolator itr(nbFrames, 7.5f);
1804    s_curve_interpolator itg(nbFrames, 8.0f);
1805    s_curve_interpolator itb(nbFrames, 8.5f);
1806
1807    v_stretch vverts(hw_w, hw_h);
1808    glEnable(GL_BLEND);
1809    glBlendFunc(GL_ONE, GL_ONE);
1810    for (int i=0 ; i<nbFrames ; i++) {
1811        float x, y, w, h;
1812        const float vr = itr(i);
1813        const float vg = itg(i);
1814        const float vb = itb(i);
1815
1816        // clear screen
1817        glColorMask(1,1,1,1);
1818        glClear(GL_COLOR_BUFFER_BIT);
1819        glEnable(GL_TEXTURE_2D);
1820
1821        // draw the red plane
1822        vverts(vtx, vr);
1823        glColorMask(1,0,0,1);
1824        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1825
1826        // draw the green plane
1827        vverts(vtx, vg);
1828        glColorMask(0,1,0,1);
1829        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1830
1831        // draw the blue plane
1832        vverts(vtx, vb);
1833        glColorMask(0,0,1,1);
1834        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1835
1836        // draw the white highlight (we use the last vertices)
1837        glDisable(GL_TEXTURE_2D);
1838        glColorMask(1,1,1,1);
1839        glColor4f(vg, vg, vg, 1);
1840        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1841        hw.flip(screenBounds);
1842    }
1843
1844    h_stretch hverts(hw_w, hw_h);
1845    glDisable(GL_BLEND);
1846    glDisable(GL_TEXTURE_2D);
1847    glColorMask(1,1,1,1);
1848    for (int i=0 ; i<nbFrames ; i++) {
1849        const float v = itg(i);
1850        hverts(vtx, v);
1851        glClear(GL_COLOR_BUFFER_BIT);
1852        glColor4f(1-v, 1-v, 1-v, 1);
1853        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1854        hw.flip(screenBounds);
1855    }
1856
1857    glColorMask(1,1,1,1);
1858    glEnable(GL_SCISSOR_TEST);
1859    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1860    glDeleteTextures(1, &tname);
1861    return NO_ERROR;
1862}
1863
1864status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
1865{
1866    status_t result = PERMISSION_DENIED;
1867
1868    if (!GLExtensions::getInstance().haveFramebufferObject())
1869        return INVALID_OPERATION;
1870
1871
1872    // get screen geometry
1873    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1874    const uint32_t hw_w = hw.getWidth();
1875    const uint32_t hw_h = hw.getHeight();
1876    const Region screenBounds(hw.bounds());
1877
1878    GLfloat u, v;
1879    GLuint tname;
1880    result = renderScreenToTextureLocked(0, &tname, &u, &v);
1881    if (result != NO_ERROR) {
1882        return result;
1883    }
1884
1885    // back to main framebuffer
1886    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
1887    glDisable(GL_SCISSOR_TEST);
1888
1889    GLfloat vtx[8];
1890    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
1891    glEnable(GL_TEXTURE_2D);
1892    glBindTexture(GL_TEXTURE_2D, tname);
1893    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1894    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1895    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1896    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
1897    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1898    glVertexPointer(2, GL_FLOAT, 0, vtx);
1899
1900    class s_curve_interpolator {
1901        const float nbFrames, s, v;
1902    public:
1903        s_curve_interpolator(int nbFrames, float s)
1904        : nbFrames(1.0f / (nbFrames-1)), s(s),
1905          v(1.0f + expf(-s + 0.5f*s)) {
1906        }
1907        float operator()(int f) {
1908            const float x = f * nbFrames;
1909            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
1910        }
1911    };
1912
1913    class v_stretch {
1914        const GLfloat hw_w, hw_h;
1915    public:
1916        v_stretch(uint32_t hw_w, uint32_t hw_h)
1917        : hw_w(hw_w), hw_h(hw_h) {
1918        }
1919        void operator()(GLfloat* vtx, float v) {
1920            const GLfloat w = hw_w + (hw_w * v);
1921            const GLfloat h = hw_h - (hw_h * v);
1922            const GLfloat x = (hw_w - w) * 0.5f;
1923            const GLfloat y = (hw_h - h) * 0.5f;
1924            vtx[0] = x;         vtx[1] = y;
1925            vtx[2] = x;         vtx[3] = y + h;
1926            vtx[4] = x + w;     vtx[5] = y + h;
1927            vtx[6] = x + w;     vtx[7] = y;
1928        }
1929    };
1930
1931    class h_stretch {
1932        const GLfloat hw_w, hw_h;
1933    public:
1934        h_stretch(uint32_t hw_w, uint32_t hw_h)
1935        : hw_w(hw_w), hw_h(hw_h) {
1936        }
1937        void operator()(GLfloat* vtx, float v) {
1938            const GLfloat w = hw_w - (hw_w * v);
1939            const GLfloat h = 1.0f;
1940            const GLfloat x = (hw_w - w) * 0.5f;
1941            const GLfloat y = (hw_h - h) * 0.5f;
1942            vtx[0] = x;         vtx[1] = y;
1943            vtx[2] = x;         vtx[3] = y + h;
1944            vtx[4] = x + w;     vtx[5] = y + h;
1945            vtx[6] = x + w;     vtx[7] = y;
1946        }
1947    };
1948
1949    // the full animation is 24 frames
1950    const int nbFrames = 12;
1951    s_curve_interpolator itr(nbFrames, 7.5f);
1952    s_curve_interpolator itg(nbFrames, 8.0f);
1953    s_curve_interpolator itb(nbFrames, 8.5f);
1954
1955    h_stretch hverts(hw_w, hw_h);
1956    glDisable(GL_BLEND);
1957    glDisable(GL_TEXTURE_2D);
1958    glColorMask(1,1,1,1);
1959    for (int i=nbFrames-1 ; i>=0 ; i--) {
1960        const float v = itg(i);
1961        hverts(vtx, v);
1962        glClear(GL_COLOR_BUFFER_BIT);
1963        glColor4f(1-v, 1-v, 1-v, 1);
1964        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1965        hw.flip(screenBounds);
1966    }
1967
1968    v_stretch vverts(hw_w, hw_h);
1969    glEnable(GL_BLEND);
1970    glBlendFunc(GL_ONE, GL_ONE);
1971    for (int i=nbFrames-1 ; i>=0 ; i--) {
1972        float x, y, w, h;
1973        const float vr = itr(i);
1974        const float vg = itg(i);
1975        const float vb = itb(i);
1976
1977        // clear screen
1978        glColorMask(1,1,1,1);
1979        glClear(GL_COLOR_BUFFER_BIT);
1980        glEnable(GL_TEXTURE_2D);
1981
1982        // draw the red plane
1983        vverts(vtx, vr);
1984        glColorMask(1,0,0,1);
1985        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1986
1987        // draw the green plane
1988        vverts(vtx, vg);
1989        glColorMask(0,1,0,1);
1990        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1991
1992        // draw the blue plane
1993        vverts(vtx, vb);
1994        glColorMask(0,0,1,1);
1995        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1996
1997        hw.flip(screenBounds);
1998    }
1999
2000    glColorMask(1,1,1,1);
2001    glEnable(GL_SCISSOR_TEST);
2002    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2003    glDeleteTextures(1, &tname);
2004
2005    return NO_ERROR;
2006}
2007
2008// ---------------------------------------------------------------------------
2009
2010status_t SurfaceFlinger::turnElectronBeamOffImplLocked()
2011{
2012    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
2013    if (!hw.canDraw()) {
2014        // we're already off
2015        return NO_ERROR;
2016    }
2017    status_t result = electronBeamOffAnimationImplLocked();
2018    if (result == NO_ERROR) {
2019        hw.setCanDraw(false);
2020    }
2021    return result;
2022}
2023
2024status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
2025{
2026    if (!GLExtensions::getInstance().haveFramebufferObject())
2027        return INVALID_OPERATION;
2028
2029    class MessageTurnElectronBeamOff : public MessageBase {
2030        SurfaceFlinger* flinger;
2031        status_t result;
2032    public:
2033        MessageTurnElectronBeamOff(SurfaceFlinger* flinger)
2034            : flinger(flinger), result(PERMISSION_DENIED) {
2035        }
2036        status_t getResult() const {
2037            return result;
2038        }
2039        virtual bool handler() {
2040            Mutex::Autolock _l(flinger->mStateLock);
2041            result = flinger->turnElectronBeamOffImplLocked();
2042            return true;
2043        }
2044    };
2045
2046    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this);
2047    status_t res = postMessageSync(msg);
2048    if (res == NO_ERROR) {
2049        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
2050
2051        // work-around: when the power-manager calls us we activate the
2052        // animation. eventually, the "on" animation will be called
2053        // by the power-manager itself
2054        mElectronBeamAnimation = true;
2055    }
2056    return res;
2057}
2058
2059// ---------------------------------------------------------------------------
2060
2061status_t SurfaceFlinger::turnElectronBeamOnImplLocked()
2062{
2063    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
2064    if (hw.canDraw()) {
2065        // we're already on
2066        return NO_ERROR;
2067    }
2068    status_t result = electronBeamOnAnimationImplLocked();
2069    if (result == NO_ERROR) {
2070        hw.setCanDraw(true);
2071    }
2072    return result;
2073}
2074
2075status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
2076{
2077    if (!GLExtensions::getInstance().haveFramebufferObject())
2078        return INVALID_OPERATION;
2079
2080    class MessageTurnElectronBeamOn : public MessageBase {
2081        SurfaceFlinger* flinger;
2082        status_t result;
2083    public:
2084        MessageTurnElectronBeamOn(SurfaceFlinger* flinger)
2085            : flinger(flinger), result(PERMISSION_DENIED) {
2086        }
2087        status_t getResult() const {
2088            return result;
2089        }
2090        virtual bool handler() {
2091            Mutex::Autolock _l(flinger->mStateLock);
2092            result = flinger->turnElectronBeamOnImplLocked();
2093            return true;
2094        }
2095    };
2096
2097    postMessageAsync( new MessageTurnElectronBeamOn(this) );
2098    return NO_ERROR;
2099}
2100
2101// ---------------------------------------------------------------------------
2102
2103status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
2104        sp<IMemoryHeap>* heap,
2105        uint32_t* w, uint32_t* h, PixelFormat* f,
2106        uint32_t sw, uint32_t sh)
2107{
2108    status_t result = PERMISSION_DENIED;
2109
2110    // only one display supported for now
2111    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
2112        return BAD_VALUE;
2113
2114    if (!GLExtensions::getInstance().haveFramebufferObject())
2115        return INVALID_OPERATION;
2116
2117    // get screen geometry
2118    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
2119    const uint32_t hw_w = hw.getWidth();
2120    const uint32_t hw_h = hw.getHeight();
2121
2122    if ((sw > hw_w) || (sh > hw_h))
2123        return BAD_VALUE;
2124
2125    sw = (!sw) ? hw_w : sw;
2126    sh = (!sh) ? hw_h : sh;
2127    const size_t size = sw * sh * 4;
2128
2129    // make sure to clear all GL error flags
2130    while ( glGetError() != GL_NO_ERROR ) ;
2131
2132    // create a FBO
2133    GLuint name, tname;
2134    glGenRenderbuffersOES(1, &tname);
2135    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
2136    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2137    glGenFramebuffersOES(1, &name);
2138    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
2139    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
2140            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
2141
2142    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2143    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
2144
2145        // invert everything, b/c glReadPixel() below will invert the FB
2146        glViewport(0, 0, sw, sh);
2147        glMatrixMode(GL_PROJECTION);
2148        glPushMatrix();
2149        glLoadIdentity();
2150        glOrthof(0, hw_w, 0, hw_h, 0, 1);
2151        glMatrixMode(GL_MODELVIEW);
2152
2153        // redraw the screen entirely...
2154        glClearColor(0,0,0,1);
2155        glClear(GL_COLOR_BUFFER_BIT);
2156        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
2157        const size_t count = layers.size();
2158        for (size_t i=0 ; i<count ; ++i) {
2159            const sp<LayerBase>& layer(layers[i]);
2160            layer->drawForSreenShot();
2161        }
2162
2163        // XXX: this is needed on tegra
2164        glScissor(0, 0, sw, sh);
2165
2166        // check for errors and return screen capture
2167        if (glGetError() != GL_NO_ERROR) {
2168            // error while rendering
2169            result = INVALID_OPERATION;
2170        } else {
2171            // allocate shared memory large enough to hold the
2172            // screen capture
2173            sp<MemoryHeapBase> base(
2174                    new MemoryHeapBase(size, 0, "screen-capture") );
2175            void* const ptr = base->getBase();
2176            if (ptr) {
2177                // capture the screen with glReadPixels()
2178                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
2179                if (glGetError() == GL_NO_ERROR) {
2180                    *heap = base;
2181                    *w = sw;
2182                    *h = sh;
2183                    *f = PIXEL_FORMAT_RGBA_8888;
2184                    result = NO_ERROR;
2185                }
2186            } else {
2187                result = NO_MEMORY;
2188            }
2189        }
2190
2191        glEnable(GL_SCISSOR_TEST);
2192        glViewport(0, 0, hw_w, hw_h);
2193        glMatrixMode(GL_PROJECTION);
2194        glPopMatrix();
2195        glMatrixMode(GL_MODELVIEW);
2196
2197
2198    } else {
2199        result = BAD_VALUE;
2200    }
2201
2202    // release FBO resources
2203    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
2204    glDeleteRenderbuffersOES(1, &tname);
2205    glDeleteFramebuffersOES(1, &name);
2206    return result;
2207}
2208
2209
2210status_t SurfaceFlinger::captureScreen(DisplayID dpy,
2211        sp<IMemoryHeap>* heap,
2212        uint32_t* width, uint32_t* height, PixelFormat* format,
2213        uint32_t sw, uint32_t sh)
2214{
2215    // only one display supported for now
2216    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
2217        return BAD_VALUE;
2218
2219    if (!GLExtensions::getInstance().haveFramebufferObject())
2220        return INVALID_OPERATION;
2221
2222    class MessageCaptureScreen : public MessageBase {
2223        SurfaceFlinger* flinger;
2224        DisplayID dpy;
2225        sp<IMemoryHeap>* heap;
2226        uint32_t* w;
2227        uint32_t* h;
2228        PixelFormat* f;
2229        uint32_t sw;
2230        uint32_t sh;
2231        status_t result;
2232    public:
2233        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
2234                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2235                uint32_t sw, uint32_t sh)
2236            : flinger(flinger), dpy(dpy),
2237              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED)
2238        {
2239        }
2240        status_t getResult() const {
2241            return result;
2242        }
2243        virtual bool handler() {
2244            Mutex::Autolock _l(flinger->mStateLock);
2245
2246            // if we have secure windows, never allow the screen capture
2247            if (flinger->mSecureFrameBuffer)
2248                return true;
2249
2250            result = flinger->captureScreenImplLocked(dpy,
2251                    heap, w, h, f, sw, sh);
2252
2253            return true;
2254        }
2255    };
2256
2257    sp<MessageBase> msg = new MessageCaptureScreen(this,
2258            dpy, heap, width, height, format, sw, sh);
2259    status_t res = postMessageSync(msg);
2260    if (res == NO_ERROR) {
2261        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
2262    }
2263    return res;
2264}
2265
2266// ---------------------------------------------------------------------------
2267
2268sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2269{
2270    sp<Layer> result;
2271    Mutex::Autolock _l(mStateLock);
2272    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2273    return result;
2274}
2275
2276// ---------------------------------------------------------------------------
2277
2278Client::Client(const sp<SurfaceFlinger>& flinger)
2279    : mFlinger(flinger), mNameGenerator(1)
2280{
2281}
2282
2283Client::~Client()
2284{
2285    const size_t count = mLayers.size();
2286    for (size_t i=0 ; i<count ; i++) {
2287        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
2288        if (layer != 0) {
2289            mFlinger->removeLayer(layer);
2290        }
2291    }
2292}
2293
2294status_t Client::initCheck() const {
2295    return NO_ERROR;
2296}
2297
2298ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2299{
2300    int32_t name = android_atomic_inc(&mNameGenerator);
2301    mLayers.add(name, layer);
2302    return name;
2303}
2304
2305void Client::detachLayer(const LayerBaseClient* layer)
2306{
2307    // we do a linear search here, because this doesn't happen often
2308    const size_t count = mLayers.size();
2309    for (size_t i=0 ; i<count ; i++) {
2310        if (mLayers.valueAt(i) == layer) {
2311            mLayers.removeItemsAt(i, 1);
2312            break;
2313        }
2314    }
2315}
2316sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
2317    sp<LayerBaseClient> lbc;
2318    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
2319    if (layer != 0) {
2320        lbc = layer.promote();
2321        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2322    }
2323    return lbc;
2324}
2325
2326sp<IMemoryHeap> Client::getControlBlock() const {
2327    return 0;
2328}
2329ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
2330    return -1;
2331}
2332sp<ISurface> Client::createSurface(
2333        ISurfaceComposerClient::surface_data_t* params, int pid,
2334        const String8& name,
2335        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2336        uint32_t flags)
2337{
2338    return mFlinger->createSurface(this, pid, name, params,
2339            display, w, h, format, flags);
2340}
2341status_t Client::destroySurface(SurfaceID sid) {
2342    return mFlinger->removeSurface(this, sid);
2343}
2344status_t Client::setState(int32_t count, const layer_state_t* states) {
2345    return mFlinger->setClientState(this, count, states);
2346}
2347
2348// ---------------------------------------------------------------------------
2349
2350UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
2351    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
2352{
2353    const int pgsize = getpagesize();
2354    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
2355
2356    mCblkHeap = new MemoryHeapBase(cblksize, 0,
2357            "SurfaceFlinger Client control-block");
2358
2359    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
2360    if (ctrlblk) { // construct the shared structure in-place.
2361        new(ctrlblk) SharedClient;
2362    }
2363}
2364
2365UserClient::~UserClient()
2366{
2367    if (ctrlblk) {
2368        ctrlblk->~SharedClient();  // destroy our shared-structure.
2369    }
2370
2371    /*
2372     * When a UserClient dies, it's unclear what to do exactly.
2373     * We could go ahead and destroy all surfaces linked to that client
2374     * however, it wouldn't be fair to the main Client
2375     * (usually the the window-manager), which might want to re-target
2376     * the layer to another UserClient.
2377     * I think the best is to do nothing, or not much; in most cases the
2378     * WM itself will go ahead and clean things up when it detects a client of
2379     * his has died.
2380     * The remaining question is what to display? currently we keep
2381     * just keep the current buffer.
2382     */
2383}
2384
2385status_t UserClient::initCheck() const {
2386    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
2387}
2388
2389void UserClient::detachLayer(const Layer* layer)
2390{
2391    int32_t name = layer->getToken();
2392    if (name >= 0) {
2393        int32_t mask = 1LU<<name;
2394        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
2395            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
2396        }
2397    }
2398}
2399
2400sp<IMemoryHeap> UserClient::getControlBlock() const {
2401    return mCblkHeap;
2402}
2403
2404ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
2405{
2406    int32_t name = NAME_NOT_FOUND;
2407    sp<Layer> layer(mFlinger->getLayer(sur));
2408    if (layer == 0) {
2409        return name;
2410    }
2411
2412    // if this layer already has a token, just return it
2413    name = layer->getToken();
2414    if ((name >= 0) && (layer->getClient() == this)) {
2415        return name;
2416    }
2417
2418    name = 0;
2419    do {
2420        int32_t mask = 1LU<<name;
2421        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
2422            // we found and locked that name
2423            status_t err = layer->setToken(
2424                    const_cast<UserClient*>(this), ctrlblk, name);
2425            if (err != NO_ERROR) {
2426                // free the name
2427                android_atomic_and(~mask, &mBitmap);
2428                name = err;
2429            }
2430            break;
2431        }
2432        if (++name > 31)
2433            name = NO_MEMORY;
2434    } while(name >= 0);
2435
2436    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
2437    //        sur->asBinder().get(), name, this, mBitmap);
2438    return name;
2439}
2440
2441sp<ISurface> UserClient::createSurface(
2442        ISurfaceComposerClient::surface_data_t* params, int pid,
2443        const String8& name,
2444        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2445        uint32_t flags) {
2446    return 0;
2447}
2448status_t UserClient::destroySurface(SurfaceID sid) {
2449    return INVALID_OPERATION;
2450}
2451status_t UserClient::setState(int32_t count, const layer_state_t* states) {
2452    return INVALID_OPERATION;
2453}
2454
2455// ---------------------------------------------------------------------------
2456
2457GraphicPlane::GraphicPlane()
2458    : mHw(0)
2459{
2460}
2461
2462GraphicPlane::~GraphicPlane() {
2463    delete mHw;
2464}
2465
2466bool GraphicPlane::initialized() const {
2467    return mHw ? true : false;
2468}
2469
2470int GraphicPlane::getWidth() const {
2471    return mWidth;
2472}
2473
2474int GraphicPlane::getHeight() const {
2475    return mHeight;
2476}
2477
2478void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
2479{
2480    mHw = hw;
2481
2482    // initialize the display orientation transform.
2483    // it's a constant that should come from the display driver.
2484    int displayOrientation = ISurfaceComposer::eOrientationDefault;
2485    char property[PROPERTY_VALUE_MAX];
2486    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
2487        //displayOrientation
2488        switch (atoi(property)) {
2489        case 90:
2490            displayOrientation = ISurfaceComposer::eOrientation90;
2491            break;
2492        case 270:
2493            displayOrientation = ISurfaceComposer::eOrientation270;
2494            break;
2495        }
2496    }
2497
2498    const float w = hw->getWidth();
2499    const float h = hw->getHeight();
2500    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
2501            &mDisplayTransform);
2502    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
2503        mDisplayWidth = h;
2504        mDisplayHeight = w;
2505    } else {
2506        mDisplayWidth = w;
2507        mDisplayHeight = h;
2508    }
2509
2510    setOrientation(ISurfaceComposer::eOrientationDefault);
2511}
2512
2513status_t GraphicPlane::orientationToTransfrom(
2514        int orientation, int w, int h, Transform* tr)
2515{
2516    uint32_t flags = 0;
2517    switch (orientation) {
2518    case ISurfaceComposer::eOrientationDefault:
2519        flags = Transform::ROT_0;
2520        break;
2521    case ISurfaceComposer::eOrientation90:
2522        flags = Transform::ROT_90;
2523        break;
2524    case ISurfaceComposer::eOrientation180:
2525        flags = Transform::ROT_180;
2526        break;
2527    case ISurfaceComposer::eOrientation270:
2528        flags = Transform::ROT_270;
2529        break;
2530    default:
2531        return BAD_VALUE;
2532    }
2533    tr->set(flags, w, h);
2534    return NO_ERROR;
2535}
2536
2537status_t GraphicPlane::setOrientation(int orientation)
2538{
2539    // If the rotation can be handled in hardware, this is where
2540    // the magic should happen.
2541
2542    const DisplayHardware& hw(displayHardware());
2543    const float w = mDisplayWidth;
2544    const float h = mDisplayHeight;
2545    mWidth = int(w);
2546    mHeight = int(h);
2547
2548    Transform orientationTransform;
2549    GraphicPlane::orientationToTransfrom(orientation, w, h,
2550            &orientationTransform);
2551    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2552        mWidth = int(h);
2553        mHeight = int(w);
2554    }
2555
2556    mOrientation = orientation;
2557    mGlobalTransform = mDisplayTransform * orientationTransform;
2558    return NO_ERROR;
2559}
2560
2561const DisplayHardware& GraphicPlane::displayHardware() const {
2562    return *mHw;
2563}
2564
2565DisplayHardware& GraphicPlane::editDisplayHardware() {
2566    return *mHw;
2567}
2568
2569const Transform& GraphicPlane::transform() const {
2570    return mGlobalTransform;
2571}
2572
2573EGLDisplay GraphicPlane::getEGLDisplay() const {
2574    return mHw->getEGLDisplay();
2575}
2576
2577// ---------------------------------------------------------------------------
2578
2579}; // namespace android
2580