SurfaceFlinger.cpp revision f20a32415d055336bc6016fa2de36d126db32746
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
54a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
72cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
75375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
78375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
80a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
83abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
85bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
8873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
933330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
11278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1207303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1257e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
12896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
12996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1499a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1519a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
152b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1708b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1713330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
172a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2107303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2117303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
271a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
2728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2860408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
295bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
296f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
297bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3030408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
309bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3170408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
344bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
345bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
375a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
376a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
377a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
378a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
379a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3818a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
38335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
38535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
38635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
39135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
39274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
39374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
39435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
3958392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
3968392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
397c479e18db0216f7096fefe85ffa71ab00329aef3Mathias Agopian        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
403e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
433abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
43762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
44359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4584da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4613d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
468ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian        invalidateHwcGeometry();
4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4724da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4734da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
476a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4790852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4800852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4810852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4820852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4873d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4893d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
521c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
539064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
540064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
55148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5605d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5610aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
579ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
580ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
594970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
617970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
619970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
631ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
655a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
666a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
670ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
678ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6808b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
685970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
691970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
692970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
693970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
694970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
710a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    LayerVector& currentLayers(
711a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7284da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7294da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7314da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
734ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian            invalidateHwcGeometry();
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
741ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
742ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
743ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
744ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
745ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
763076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
765b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
770a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
771a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
772a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
773a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
774a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
775a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
777a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
77845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
77945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
78045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
78173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            if (mDebugDisableHWC) {
78273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
78373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
78473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
785a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
786a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
787a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
791b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
792b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
798b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
799b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
800b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
801b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
8048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8058b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
806df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
80729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
80929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
81029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
811b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
81229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
81329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
81429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
81529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
81629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
81729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
81829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
81929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
82195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
82229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
823df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
82495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
82529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
82829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
848a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
849a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    status_t err = NO_ERROR;
8504da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
85145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
852a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
853a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
854a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(hw.getHwComposer());
85545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
856a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
85745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    LOGE_IF(cur && hwc.getNumLayers() != count,
85845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
85945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
860a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
86224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
86324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
86424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
865a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
86845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
86945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
87045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    Region transparent;
87145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    if (cur) {
87245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
87345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
87445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->setPerFrameData(&cur[i]);
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
87645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        err = hwc.prepare();
87745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
879f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian        if (err == NO_ERROR) {
880f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
881f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                if (cur[i].hints & HWC_HINT_CLEAR_FB) {
882f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const sp<LayerBase>& layer(layers[i]);
883f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    if (!(layer->needsBlending())) {
884f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                        transparent.orSelf(layer->visibleRegionScreen);
885f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    }
886f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                }
887f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
888f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian
889f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            /*
890f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian             *  clear the area of the FB that need to be transparent
891f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian             */
892f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            transparent.andSelf(dirty);
893f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            if (!transparent.isEmpty()) {
894f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                glClearColor(0,0,0,0);
895f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                Region::const_iterator it = transparent.begin();
896f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                Region::const_iterator const end = transparent.end();
897f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                const int32_t height = hw.getHeight();
898f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                while (it != end) {
899f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const Rect& r(*it++);
900f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    const GLint sy = height - (r.top + r.height());
901f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    glScissor(r.left, sy, r.width(), r.height());
902f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                    glClear(GL_COLOR_BUFFER_BIT);
903f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian                }
904f20a32415d055336bc6016fa2de36d126db32746Mathias Agopian            }
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
906a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (cur) {
914586a0deb76012c4347298c11df460631853b67f8Antti Hatala            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
915586a0deb76012c4347298c11df460631853b67f8Antti Hatala                !(cur[i].flags & HWC_SKIP_LAYER)) {
91645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                // skip layers handled by the HAL
91745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                continue;
91845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            }
91945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
92073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
92145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
92245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
92345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
92445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
92545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
92645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
933076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
935076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
9440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9510a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
953df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9610a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
9640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
96620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
96720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
96820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
96920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9790a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
980b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
981b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
982b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
983b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
984b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
9870a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
10070a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
100820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
100920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
101020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
101120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10237f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10241f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
10251f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
10261f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
10270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
103420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
103520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
103620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
103720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1043ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1044ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1065076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1075f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
10761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
10771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
10781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
107996f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
108096f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
10811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
108296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
108396f0819f81293076e652792794a961543e6750d7Mathias Agopian
108496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
108596f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
108696f0819f81293076e652792794a961543e6750d7Mathias Agopian
108796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
108896f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
108996f0819f81293076e652792794a961543e6750d7Mathias Agopian
109096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
109196f0819f81293076e652792794a961543e6750d7Mathias Agopian}
109296f0819f81293076e652792794a961543e6750d7Mathias Agopian
109396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
109496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
109596f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
109696f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
109796f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
109896f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
109996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1102076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1104b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1105b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1106b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1107b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1110076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11133d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
111876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
111976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
11209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
112176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
112276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
112376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
11248c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11250b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
11260b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11273d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11283d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
112996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
113096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11329a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
113496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
113696f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
113796f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
113896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1146bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1150bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1164cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
11658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        // if there is a transaction with a resize, wait for it to
1166cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1167cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1168cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1169448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1170448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1171448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1172448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1173448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1174448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1175448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1176448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1177cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
119162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
120562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1210c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1218c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
122996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
12307e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1234076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
12366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12376e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12386e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12406e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12416e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12428b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1244b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1247a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1248a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12511293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12521293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
125496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1258076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
125996f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1260285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
126196f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
126596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
12661c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
12671c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
12681c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
12691c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1270b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1271b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1273b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12741c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
127696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1283f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
128496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12851c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1294a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1295a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1296a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
12978f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1298a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1302a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1303a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1304a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1305a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1306a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
130796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1308f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
130996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1311076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1317f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13308b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
133648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
133896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
133948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
134048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
134148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
134248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
134348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
13489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1350759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
13518b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1352f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
13530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1354f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1355f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
13560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
13570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
13580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1359f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1360cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1361cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1362f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1363759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
13648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * remove the layer from the current list -- chances are that it's
13658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * not in the list anyway, because it should have been removed
13668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * already upon request of the client (eg: window manager).
1367759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1368759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1369759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1370759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1371cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
137276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian            if (err == NAME_NOT_FOUND) {
137376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // The surface wasn't in the current list, which means it was
137476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // removed already, which means it is in the purgatory,
137576cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // and need to be removed from there.
137676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // This needs to happen from the main thread since its dtor
137776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // must run from there (b/c of OpenGL ES). Additionally, we
137876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // can't really acquire our internal lock from
137976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                // destroySurface() -- see postMessage() below.
138076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                ssize_t idx = flinger->mLayerPurgatory.remove(l);
138176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                LOGE_IF(idx < 0,
138276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian                        "layer=%p is not in the purgatory list", l.get());
138376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian            }
138476cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian
13858c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
13868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1387f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1388f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1389f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
13903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1391bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
139696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
140396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
140496f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1405076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1412f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1414f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1415f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1422cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1424cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1425cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14671d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1470375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
15031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
15041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
15229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
153673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
153773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
153873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
153973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC ? "disabled" : "enabled");
154073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
15418372785879d329f592f6883620b5a32d80d74691Mathias Agopian        hwc.dump(result, buffer, SIZE);
154273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
15433330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15451d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
15469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
156659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
15679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1572a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1573375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1574375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1575375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1576375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
15781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
15791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
15801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
15811b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
15821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
15831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
15841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
15851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
15861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
15871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
15881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
15891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
15901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
15911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
15941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1597b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1598375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1599375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1600375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1601375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1602375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1603375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
160801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
160935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
161973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            case 1008:  // toggle use of hw composer
162073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                n = data.readInt32();
162173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC = n ? 1 : 0;
1622ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian                invalidateHwcGeometry();
162373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                // fall-through...
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1629cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1630cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1631cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
163535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
163635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
163735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
163835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
163935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
16420408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
164501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166159119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
166259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
16649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
166559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
166659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
166759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
166859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
166959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
167059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
167159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
167259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
167359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
167459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
167559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
167659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
167759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
167859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
167959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
168059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
168159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
168259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
16839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
168559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1686015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
168759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
168859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
16899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
169159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
169259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
169359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
169459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
169559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
169859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
17019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
17029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
17059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
17079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
170859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
171359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
17159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
171959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
172159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
172559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
172859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
17309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
17319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
17329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
173459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
174159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
17839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
17889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
178959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const int nbFrames = 12;
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
18059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
18069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
182159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
183859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
183959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
19189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
191959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
19459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1950a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
1951a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1969a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
197859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
198059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
200059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
200159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
20039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
20049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
200559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
200659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
20119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2012abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
20139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
20159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2019abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2020abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2021abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2022abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2023abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2024abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2025abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
2026abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2027abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
2028abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2029abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2030015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(false);
2031015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
203759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2038abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
204059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2041abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2042abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
204359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
204459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2049abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
205159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
205359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2054abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
205559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
205659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
205759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2062abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
206359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
206459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
206559119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
206659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2069abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2076abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2077abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2078abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2079015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(true);
2080a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2081a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2082a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2083a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2084a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2085015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
20869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
20899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
20919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2092abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
20939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
20949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2095abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2096abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
20979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
20999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
21009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
21029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2103abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
21049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
21059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2108abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
21099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
21109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
21119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
211474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
211574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
211674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2117bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2118bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
211974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
212074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
212174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
212374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
212474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
212574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
212774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
212874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
213074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
213174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
213274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
213374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
213474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
213574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
213674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
213774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
213874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
213974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
214074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2141c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian    LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2142c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian            sw, sh, minLayerZ, maxLayerZ);
2143c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
214474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
214574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
214674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
214774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
214874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
214974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
215074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
215174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
215274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
215374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
215474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
215574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
215674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
215774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2158c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
2159c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian    LOGD("screenshot: FBO created, status=0x%x", status);
2160c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
216174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
216274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
216374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
216474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2165f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
216674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
216774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
216874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
216974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glOrthof(0, hw_w, 0, hw_h, 0, 1);
217074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
217174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
217274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2175f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
2176c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian        LOGD("screenshot: glClear() issued");
2177c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
217874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
217974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        const size_t count = layers.size();
218074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2182bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            const uint32_t z = layer->drawingState().z;
2183bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
2184bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                layer->drawForSreenShot();
2185bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
218774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2188c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian        LOGD("screenshot: All layers rendered");
2189c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
219074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
219474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
219574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
219674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
219774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
219874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
219974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
220074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
220174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
220274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
220374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
2204c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
2205c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian                LOGD("screenshot: about to call glReadPixels(0,0,%d,%d,...,%p)",
2206c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian                        sw, sh, ptr);
2207c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
220974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
221274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
221374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
221474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
221574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
221674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
221874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
221974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
2220c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
2221c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian            LOGD("screenshot: glReadPixels() returned %s", strerror(result));
2222c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
222474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
222574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
222674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
222774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
222874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
222974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
223074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
223174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
223274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2233c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian    LOGD("screenshot: about to release FBO resources");
2234c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
223574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
223674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
223774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
223874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2239e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2240c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian    LOGD("screenshot: about to call compositionComplete()");
2241c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
2242e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2243e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2244c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian    LOGD("screenshot: result = %s", strerror(result));
2245c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
224674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
224774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
224974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
22511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
225274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2253bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2254bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
22551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
22561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
22571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
22581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
22591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
22621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
22641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
22651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
22661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
22671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
22681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
22691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
227074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
227174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2272bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2273bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
22741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
22751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
22761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
227774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2278bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2279bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
22801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2281bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2282bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2283bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
22841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
22851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
22871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
22881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
22901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
22911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
22931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
22941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
22951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
229674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2297bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
22981b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22991b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
23001b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
23011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
23021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2304bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
23051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
23061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
23071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
23081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
23091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
23101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
23111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
23121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
23131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
23217303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
232396f0819f81293076e652792794a961543e6750d7Mathias Agopian
2324b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
232996f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
233096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
233196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
233296f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
233396f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
233496f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
233596f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
233696f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2339076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
234096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2343076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
234496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
234796f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
234896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2351b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
235296f0819f81293076e652792794a961543e6750d7Mathias Agopian{
235396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
235496f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
235596f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
235696f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
235796f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
235896f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
235996f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
236096f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
236196f0819f81293076e652792794a961543e6750d7Mathias Agopian}
2362076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
2363076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
236496f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
236596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
236696f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
236796f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2368076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2369076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
237296f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
2373b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2374b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2375b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
2376b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
2377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
237896f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
2379b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2380b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2381b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
238496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
238596f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
2386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
238796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
238896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
2389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
239096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
239196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
2392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2395b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2396b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
2397b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
2398b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2399b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
2400b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
2401b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2402b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
2403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
2404b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
2406b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
2407b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
2408b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2411b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
2412b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2413b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
2414b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
2415b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2416b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2417b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
2419b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
2420b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
2421b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
2422b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
2423b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
2424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
2425b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
2426b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
2427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
2428b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2429b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
2432b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
2433b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2434b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
2436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
2438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
2439579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
2440579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
2441579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
2442579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2443b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2444b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2445b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2446b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
2447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
2448b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2449b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2450b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
2451b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2452b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
2453b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
245489c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if (layer == 0) {
245589c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis        return name;
245689c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
2457b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2458579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
2459b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
246089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if ((name >= 0) && (layer->getClient() == this)) {
2461579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
246289c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
2463b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2464b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
2465b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
2466b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
2467b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
2468b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
2469579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
2470579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
2471579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
2472579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
2473579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
2474579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
2475579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
2476b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
2477b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2478b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
2479b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
2480b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
2481b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
248253503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
248353503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
2484b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
2485b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2486b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2487b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
2488b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2489b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2490b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2491b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
2492b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2493b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2494b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
2495b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2496b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2497b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
2498b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2499b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2500b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2501b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
25049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
25069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
25089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        PixelFormat format, uint32_t usage) {
25099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
25109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
25119a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    if (err != 0) {
25129a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        LOGE("createGraphicBuffer: init check failed: %d", err);
25139a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    } else if (graphicBuffer->handle == 0) {
25159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
25169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
25179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    Mutex::Autolock _l(mLock);
25199a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    mBuffers.add(graphicBuffer);
25209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
25219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25229a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25239a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennisvoid GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
25249a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    Mutex::Autolock _l(mLock);
25259a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    if (0 <= bufIdx && bufIdx < mBuffers.size()) {
25269a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        sp<GraphicBuffer> b(mBuffers[bufIdx]);
25279a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        mBuffers.clear();
25289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        mBuffers.add(b);
25299a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    } else {
25309a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        mBuffers.clear();
25319a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
25329a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
25339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
25349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
25359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
25502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
25542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
25552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
25562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
25582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
25592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
25602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
25622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
25632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
25642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
25652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
25662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
25672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
25682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
25692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
25702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
25722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
25732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
25742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
25752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
25762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
25782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
25792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
25802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
25812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
25822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
25832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
25842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
25852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
25862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
25872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
25882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2594eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2595eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2598eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2599eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2601eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2604eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2607eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2612eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
26202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
26222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
26232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
26242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
26252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
26262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
26272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2628eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2629eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2630eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2631eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2632eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2634eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
26350d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
26362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264459119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
264559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
264659119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
264759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2652076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2653076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2654076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2655076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2659