SurfaceFlinger.cpp revision a7f0373533e590fdca1400f90e6657ebb2dd5f17
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
73cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
79375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        mElectronBeamAnimation(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
85bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
923330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
11178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1247303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1297e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
13396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13596f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
149b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
150b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
151b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
169a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1703330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
171a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2097303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2107303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_PACK_ALIGNMENT, 4);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
269a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
271a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2850408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
294bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
295f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
296bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
308bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
344bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3758a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
37735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
37835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
37935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
38035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
38535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
38674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
38774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // release the clients before we flip ('cause flip might block)
38935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        postFramebuffer();
39435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
39535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
4279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        if (mElectronBeamAnimation)
4289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            SurfaceFlinger::turnElectronBeamOn(0);
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
43262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
43859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4573d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
4634da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4720852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4730852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4740852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4750852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
514c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
532064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
533064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
54448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5483d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5535d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
587970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
610970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
612970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
648a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
659a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
678970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
684970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
685970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
686970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
696cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
703000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    LayerVector& currentLayers = const_cast<LayerVector&>(
704000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian            mDrawingState.layersSortedByZ);
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
757b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
760b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
761b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
762b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
763b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
764b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
765b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
771b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
772b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
773b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
774b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
777df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
778df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        (flags & DisplayHardware::BUFFER_PRESERVED))
779df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
78029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
78129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
78229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
78329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
784b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
78529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
78629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
78729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
78829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
78929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
79029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
79129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
79229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
79495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
79529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
796df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
79795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
79829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
80129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
822000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    const size_t count = layers.size();
823000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    for (size_t i=0 ; i<count ; ++i) {
82445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
82545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
82645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
82745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
82845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
82945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
836076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
838076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
8460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
8470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
8490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
8500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
8510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
8520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
8530a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
8540a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8550a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
856df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
8620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
8630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
8640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
8650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
8660a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
8670926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
87020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
87120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
87220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8820a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
883b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
884b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
885b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
886b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
887b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
8900a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
9100a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
91120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
91220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
91320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
91420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
9267f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
9271f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
9281f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
9291f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
9300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
93720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
93820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
93920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
94020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
966076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
974076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
976f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
9771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
9781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
9791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
98096f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
98196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
9821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
98396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
98496f0819f81293076e652792794a961543e6750d7Mathias Agopian
98596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
98696f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
98796f0819f81293076e652792794a961543e6750d7Mathias Agopian
98896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
98996f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
99096f0819f81293076e652792794a961543e6750d7Mathias Agopian
99196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
99296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
99396f0819f81293076e652792794a961543e6750d7Mathias Agopian
99496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
99596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
99696f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
99796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
99896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
99996f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
100096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1003076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1005b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1006b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1007b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1008b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1011076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10198c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
10209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
10218c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
10220b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
10230b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
10243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
10253d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
102696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
102796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
10289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
10299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
103196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
103396f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
103496f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
103596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1043bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1047bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1061cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1062cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // if there is a transaction with a resize, wait for it to
1063cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1064cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1065cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1066448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1067448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1068448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1069448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1070448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1071448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1072448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1073448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1074cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
108862b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
110262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1106c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy,
1107c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1115c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
11277e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1131076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
11336e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
11346e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
11356e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
11366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
11376e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
11386e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
11396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
114596f0819f81293076e652792794a961543e6750d7Mathias Agopian                layer = createPushBuffersSurface(client, d, w, h, flags);
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                layer = normalLayer;
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
115296f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createBlurSurface(client, d, w, h, flags);
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
115596f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1159076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
116096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1161285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
116296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1163b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
11651c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        if (surfaceHandle != 0) {
116696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
11671c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
11681c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
11691c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
11701c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1171b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1172b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1173b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1174b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
11751c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1176b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
117796f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1183b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1184f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
118596f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
11861c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1195a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1196a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1197a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
11988f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1199a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1203a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1204a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1205a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1206a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1207a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
120896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1209f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
121096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1212076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1217b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface(
1218f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
121996f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1226b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1227f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
122896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1235b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1236f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
123796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
124496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
12459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
12469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
12479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
12489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
12490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     *
12500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
12510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
12520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
12539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
12549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
125548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
12560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
125796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
125848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
125948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
126048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
126148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
126248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
12639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
12649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
12659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
12679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1269759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
12709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1271f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
12720aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1273f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1274f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
12750aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
12760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
12770aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1278f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1279cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1280cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1281f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1282759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
1283759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * remove the layer from the current list -- chances are that it's
1284759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * not in the list anyway, because it should have been removed
1285759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * already upon request of the client (eg: window manager).
1286759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1287759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1288759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1289759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1290cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
12918c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
12928c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1295f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
12963d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1297bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
130296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
130996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1311076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1318f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1320f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1321f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1330cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1331cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1376375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
13839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
13859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
13869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
13879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
13889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
13899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
13909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
13929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
13939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
13949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
13959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
13969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
13979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
13989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
13999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE,
14019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
14091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
14101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
14111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
14249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
14259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
14269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
14279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
14289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
14291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
14319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
14329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
14339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14369795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
14379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
14389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
14399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14423330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
14449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
14469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
14479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
146459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
14659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1470a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1471375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1472375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1473375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1474375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
14761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
14771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
14781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
14791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
14801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
14811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
14821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
14831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
14841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
14851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
14861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
14871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
14881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
14891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
14921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1495b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1496375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1497375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1498375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1499375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1500375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1501375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
150601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
150735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1522cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1523cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1524cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1526cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
152835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
152935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
153035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
153135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
153235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
15350408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
153801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
155459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
155559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
15569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
15579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
155859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
155959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
156059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
156159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
156259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
156359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
156459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
156559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
156659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
156759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
156859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
156959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
157059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
157159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
157259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
157359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
157459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
157559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
15769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
15779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
157859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1579015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
158059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
158159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
15829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
15839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
158459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
158559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
158659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
158759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
158859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
15899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
15909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
159159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
15929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
15939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
15949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
15959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
15969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
15979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
15989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
15999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
16009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
160159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
16039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
16049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
16059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
160659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
16089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
16099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
16109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
16119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
161259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
161459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
16169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
16179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
161859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
16209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
162159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
16239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
16249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
16259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
16269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
162759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
16299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
16309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
16319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
16329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
16339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
163459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
16369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
16379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
16389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
16399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
16409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
16419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
16429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
16439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
16449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
16459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
16469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
16479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
16489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
16499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
16509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
16519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
16529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
16539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
16549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
16559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
16569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
16579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
16589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
16599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
16609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
16619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
16629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
16639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
16649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
16659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
16669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
16679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
16689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
16699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
16709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
16719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
16729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
16739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
16749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
16759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
16769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
16779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
16789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
16799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
16809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
16819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
168259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
16839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
16859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
16869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
16879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
16889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
16899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
16919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
16929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
16939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
16949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
16959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const int nbFrames = 12;
16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
16989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
17029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
17059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
17079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
17089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
17139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
171459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
17219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
17229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
17289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
173159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
173259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
17419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
17539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
17569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
181259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const int nbFrames = 12;
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
187059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
187259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
189259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
189359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
189759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
189859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked()
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
1911015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    electronBeamOffAnimationImplLocked();
1912015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(false);
1913015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
191459119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
191559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
191659119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
191759119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
191859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
191959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
192059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
192159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
192259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger)
192359119e658a12279e8fff508f8773843de2d90917Mathias Agopian            : flinger(flinger), result(PERMISSION_DENIED) {
192459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
192559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
192659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
192759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
192859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
192959119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
193059119e658a12279e8fff508f8773843de2d90917Mathias Agopian            result = flinger->turnElectronBeamOffImplLocked();
193159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
193259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
193359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
193459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
193559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this);
193659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
193759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
193859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        mElectronBeamAnimation = true;
194459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
194659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
194759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked()
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
1957015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    electronBeamOnAnimationImplLocked();
1958015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(true);
1959a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
1960a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
1961a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
1962a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
1963a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
1964015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger)
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            : flinger(flinger), result(PERMISSION_DENIED) {
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            result = flinger->turnElectronBeamOnImplLocked();
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this) );
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1992df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
1993df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        sp<IMemoryHeap>* heap,
1994df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
1995df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t sw, uint32_t sh)
1996df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian{
1997df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    status_t result = PERMISSION_DENIED;
1998df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
1999df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    // only one display supported for now
2000df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
2001df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        return BAD_VALUE;
2002df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2003df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
2004df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        return INVALID_OPERATION;
2005df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2006df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    // get screen geometry
2007df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
2008df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    const uint32_t hw_w = hw.getWidth();
2009df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    const uint32_t hw_h = hw.getHeight();
2010df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2011df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    if ((sw > hw_w) || (sh > hw_h))
2012df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        return BAD_VALUE;
2013df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2014df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    sw = (!sw) ? hw_w : sw;
2015df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    sh = (!sh) ? hw_h : sh;
2016df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    const size_t size = sw * sh * 4;
2017df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2018df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    // make sure to clear all GL error flags
2019df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
2020df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2021df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    // create a FBO
2022df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    GLuint name, tname;
2023df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glGenRenderbuffersOES(1, &tname);
2024df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
2025df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2026df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glGenFramebuffersOES(1, &name);
2027df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
2028df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
2029df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
2030df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2031df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2032df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
2033df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2034df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
2035df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glViewport(0, 0, sw, sh);
2036df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glMatrixMode(GL_PROJECTION);
2037df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glPushMatrix();
2038df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glLoadIdentity();
2039df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glOrthof(0, hw_w, 0, hw_h, 0, 1);
2040df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glMatrixMode(GL_MODELVIEW);
2041df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2042df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        // redraw the screen entirely...
2043df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glClearColor(0,0,0,1);
2044df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2045df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
2046df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        const size_t count = layers.size();
2047df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
2048df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
2049df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            layer->drawForSreenShot();
2050df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        }
2051df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2052df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        // XXX: this is needed on tegra
2053df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glScissor(0, 0, sw, sh);
2054df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2055df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        // check for errors and return screen capture
2056df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        if (glGetError() != GL_NO_ERROR) {
2057df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            // error while rendering
2058df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            result = INVALID_OPERATION;
2059df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        } else {
2060df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            // allocate shared memory large enough to hold the
2061df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            // screen capture
2062df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            sp<MemoryHeapBase> base(
2063df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
2064df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            void* const ptr = base->getBase();
2065df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            if (ptr) {
2066df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                // capture the screen with glReadPixels()
2067df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
2068df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                if (glGetError() == GL_NO_ERROR) {
2069df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    *heap = base;
2070df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    *w = sw;
2071df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    *h = sh;
2072df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
2073df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    result = NO_ERROR;
2074df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                }
2075df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            } else {
2076df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                result = NO_MEMORY;
2077df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            }
2078df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        }
2079df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2080df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glEnable(GL_SCISSOR_TEST);
2081df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glViewport(0, 0, hw_w, hw_h);
2082df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glMatrixMode(GL_PROJECTION);
2083df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glPopMatrix();
2084df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        glMatrixMode(GL_MODELVIEW);
2085df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2086df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2087df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    } else {
2088df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        result = BAD_VALUE;
2089df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    }
2090df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2091df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    // release FBO resources
2092df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
2093df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glDeleteRenderbuffersOES(1, &tname);
2094df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    glDeleteFramebuffersOES(1, &name);
2095df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian    return result;
2096df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian}
2097df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
2098df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian
20991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
21001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
2101df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2102df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t sw, uint32_t sh)
21031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
21041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
21051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
21061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
21071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
21091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
21101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
21121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
21131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
21141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
21151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
21161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
21171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
2118df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t sw;
2119df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian        uint32_t sh;
21201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
21211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
21221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
2123df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2124df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                uint32_t sw, uint32_t sh)
21251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2126df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED)
21271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
21281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
21301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
21311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
21331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
21341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
21361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
21371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
21381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2139df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2140df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian                    heap, w, h, f, sw, sh);
21411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
21431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
21441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
21451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2147df85c455c34a920d22a8e3f7459a1cc615efcd27Mathias Agopian            dpy, heap, width, height, format, sw, sh);
21481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
21491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
21501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
21511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
21521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
21531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
21541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
21551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
21561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2159b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2160b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2161b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2162b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2163b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
21647303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2165b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
216696f0819f81293076e652792794a961543e6750d7Mathias Agopian
2167b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2168b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2169b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
217296f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
217396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
217496f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
217596f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
217696f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
217796f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
217896f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
217996f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2182076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
218396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2184b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2186076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
218796f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2189b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
219096f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
219196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2194b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
219596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
219696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
219796f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
219896f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
219996f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
220096f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
220196f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
220296f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
220396f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
220496f0819f81293076e652792794a961543e6750d7Mathias Agopian}
2205076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
2206076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
220796f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
220896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
220996f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
221096f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2211076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2212076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221596f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
2216b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2217b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2218b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
2219b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
2220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
222196f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
2222b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2223b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2224b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
222796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
222896f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
2229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
223196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
223496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2238b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2239b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
2240b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
2241b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2242b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
2243b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
2244b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2245b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
2246b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
2247b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2248b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
2249b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
2250b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
2251b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2252b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2254b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
2255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2256b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
2257b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
2258b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2259b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2260b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2261b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
2262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
2263b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
2264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
2265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
2266b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
2267b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
2268b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
2269b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
2270b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
2271b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2273b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2274b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
2275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
2276b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
2279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
2281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
2282579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
2283579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
2284579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
2285579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2289b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
2290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
2291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
2294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
2296b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
2297b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (layer == 0) return name;
2298b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2299579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
2300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
2301579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if ((name >= 0) && (layer->getClient() == this))
2302579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
2303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
2305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
2306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
2307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
2308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
2309579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
2310579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
2311579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
2312579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
2313579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
2314579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
2315579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
2316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
2317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
2321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
232253503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
232353503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
2324b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
2325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
2328b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2330b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2331b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
2332b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2333b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2334b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
2335b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2336b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2337b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
2338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
23572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
23612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
23622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
23632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
23642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
23652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
23662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
23672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
23682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
23692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
23702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
23712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
23722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
23732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
23742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
23752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
23762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
23772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
23782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
23792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
23802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
23812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
23822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
23832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
23842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
23852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
23862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
23872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
23882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
23892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
23902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
23912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
23922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
23932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
23942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
23952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
23962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2401eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2402eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2405eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2406eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2408eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2411eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2414eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2419eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
24272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
24282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
24292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
24302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
24312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
24322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
24332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
24342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2435eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2436eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2437eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2438eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2439eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2441eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
24420d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
24432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245159119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
245259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
245359119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
245459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2459076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2460076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2461076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2462076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2466