SurfaceFlinger.cpp revision f653b897a449e10d6cbfb6e0812f7b0bb02d6482
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
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1658b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1663330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
167a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1977303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
1987303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
1997303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2007303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
265a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
266a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
2678b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
279f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
280f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2810408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
282f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
290bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
292bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2930408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2940408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
2950408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
2960408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
304bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3050408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3080408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
319f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
323f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
328bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
330bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
370a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
371a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
372a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
373a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
374a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3768a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
37835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
37935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
38035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
38135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
38635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
38774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
38874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
38935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
3908392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
3918392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
392c479e18db0216f7096fefe85ffa71ab00329aef3Mathias Agopian        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
398e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian        hw.compositionComplete();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
4269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // this is a temporary work-around, eventually this should be called
4279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager
428abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
43262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
43859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        if (hw.isScreenAcquired()) {
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4573d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
463a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty = true;
4644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4674da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
471a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4723d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4740852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4750852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4760852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4770852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
516c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
534064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
535064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
54648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5493d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5510aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5555d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
575ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
589970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
612970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
614970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
650a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
661a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
673ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6758b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
680970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
686970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
688970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
689970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
698cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
699cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
705a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    LayerVector& currentLayers(
706a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
729a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            mHwWorkListDirty = true;
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
753076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
755b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
760a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
761a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
762a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
763a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
764a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
765a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
766a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
767a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
76845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
76945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
77045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
77173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            if (mDebugDisableHWC) {
77273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
77373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
77473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
775a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
777a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
778b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
781b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
782b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
788b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
789b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
790b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
791b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
7948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
7958b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
796df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
79729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
79829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
79929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
80029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
801b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
80229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
80329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
80429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
80529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
80629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
80729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
80929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
81195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
81229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
813df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
81495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
81529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
81829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
838a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
839a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    status_t err = NO_ERROR;
8404da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
84145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
842a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
843a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
844a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(hw.getHwComposer());
84545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
846a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
84745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    LOGE_IF(cur && hwc.getNumLayers() != count,
84845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
84945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
850a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
85145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
85224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
85324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
85424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
855a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
85645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
85745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
85845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
85945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
86045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    Region transparent;
86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    if (cur) {
86245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
86345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
86445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->setPerFrameData(&cur[i]);
86545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            if (cur[i].hints & HWC_HINT_CLEAR_FB) {
86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                if (!(layer->needsBlending())) {
86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
86845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                }
869a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            }
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
87145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        err = hwc.prepare();
87245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
874a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
87545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
87645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  clear the area of the FB that need to be transparent
87745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    transparent.andSelf(dirty);
879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (!transparent.isEmpty()) {
880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        glClearColor(0,0,0,0);
881a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator it = transparent.begin();
882a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator const end = transparent.end();
883a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const int32_t height = hw.getHeight();
884a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        while (it != end) {
885a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const Rect& r(*it++);
886a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const GLint sy = height - (r.top + r.height());
887a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glScissor(r.left, sy, r.width(), r.height());
888a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
89245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
89345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
89445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
89545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (cur) {
898586a0deb76012c4347298c11df460631853b67f8Antti Hatala            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
899586a0deb76012c4347298c11df460631853b67f8Antti Hatala                !(cur[i].flags & HWC_SKIP_LAYER)) {
90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                // skip layers handled by the HAL
90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                continue;
90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            }
90345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
90473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
90945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
917076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
919076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9260a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9270a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
9280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
937df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
9480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
95120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
95220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
95320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9630a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
964b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
965b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
966b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
967b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
968b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
9710a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
9910a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
99220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
99320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
99420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
99520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10077f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10081f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
10091f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
10101f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
10110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
101820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
101920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
102020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
102120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1027ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glLoadIdentity();
1028ebeb7095961e09f5cff0c7cf2c04fa4770b2e033Mathias Agopian        glMatrixMode(GL_MODELVIEW);
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1049076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1057076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1059f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
10601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
10611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
10621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
106396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
106496f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
10651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
106696f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
106796f0819f81293076e652792794a961543e6750d7Mathias Agopian
106896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
106996f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
107096f0819f81293076e652792794a961543e6750d7Mathias Agopian
107196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
107296f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
107396f0819f81293076e652792794a961543e6750d7Mathias Agopian
107496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
107596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
107696f0819f81293076e652792794a961543e6750d7Mathias Agopian
107796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
107896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
107996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
108096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
108196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
108296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
108396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1086076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1088b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1089b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1090b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1091b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1094076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10973d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
11028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
11039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
11048c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11050b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
11060b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
110996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
111096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
111496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
111696f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
111796f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
111896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1126bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1130bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
11458b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        // if there is a transaction with a resize, wait for it to
1146cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1147cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1148cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1149448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1150448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1151448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1152448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1153448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1154448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1155448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1156448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1157cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
117162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
118562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1190c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1198c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
12107e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1214076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
12166e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12206e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12228b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1224b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1227a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            normalLayer = createNormalSurface(client, d, w, h, flags, format);
1228a5529c8778c2f407f482fc12165aeb76c0f505c2Mathias Agopian            layer = normalLayer;
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
12311293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
12321293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
123496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1238076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
123996f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1240285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
124196f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1242b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
124596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
12461c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
12471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
12481c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
12491c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1250b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1251b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1252b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12541c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
125696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1263f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
126496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12651c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1274a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1275a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1276a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
12778f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1278a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1282a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1283a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1284a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1285a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1286a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
128796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1288f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
128996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1291076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1296b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1297f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
129896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
130096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13108b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13110aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13120aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13130aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
131648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13170aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
131896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
131948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
132048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
132148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
132248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
132348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
13289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1330759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
13318b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1332f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
13330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1334f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1335f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
13360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
13370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
13380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1339f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1340cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1341cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1342f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1343759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
13448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * remove the layer from the current list -- chances are that it's
13458b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * not in the list anyway, because it should have been removed
13468b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * already upon request of the client (eg: window manager).
1347759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1348759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1349759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1350759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1351cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
13528c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
13538c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1354f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1355f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1356f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
13573d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1358bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
136396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
137096f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
137196f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1379f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1381f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1382f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1389cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1391cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1392cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14341d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1437375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
14701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
14711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
14721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
14859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
14879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
14889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
14899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
14901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
14999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
150373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
150473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
150573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
150673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC ? "disabled" : "enabled");
150773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
15088372785879d329f592f6883620b5a32d80d74691Mathias Agopian        hwc.dump(result, buffer, SIZE);
150973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
15103330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1511076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15121d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        hw.dump(result);
15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
153359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
15349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1539a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1540375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1541375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1542375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1543375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
15451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
15461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
15471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
15481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
15491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
15501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
15511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
15521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
15531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
15541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                LOGE("Permission Denial: "
15551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
15561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
15571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
15581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
15611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1564b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1565375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1566375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1567375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1568375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1569375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1570375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
157501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
157635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
158673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            case 1008:  // toggle use of hw composer
158773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                n = data.readInt32();
158873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC = n ? 1 : 0;
158973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mHwWorkListDirty = true;
159073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                // fall-through...
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1596cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1597cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1598cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1599cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1600cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
160235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
160335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
160435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
160535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
160635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
16090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
161201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
162959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
16319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
163259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
163359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
163459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
163559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
163659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
163759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
163859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
163959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
164059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
164159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
164259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
164359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
164459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
164559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
164659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
164759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
164859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
164959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
16509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
16519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
165259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
1653015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
165459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
165559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
16569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
16579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
165859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
165959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
166059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
166159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
166259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
16639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
16649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
166559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
16679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
16689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
16699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
16709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
16719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
16729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
16739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        layer->drawForSreenShot();
16749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
167559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
16779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
16789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
16799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
168059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
16829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
16839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
16849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
16859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
168659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
168859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
16909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
16919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
169259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
16949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
169559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
16969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
16979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
16989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
16999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
17009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
170159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
17039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
17049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
17059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
17069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
17079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
170859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
17109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
17119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
17129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
17139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
17149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
17159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
17169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
17179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
17189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
17199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
17219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
17229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
17249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
17259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
17269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
17289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
17299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
17309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
17329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
17349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
17359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
17379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
17389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
17409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
17419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
17429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
17439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
17449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
17459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
17469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
17479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
17489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
17509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
17529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
17539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
17549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
17559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
175659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
17579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
17589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
17599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
17609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
17619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
17629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
17639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
17649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
17659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
17669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
17679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
17689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
17709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const int nbFrames = 12;
17719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
17729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
17739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
17749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
17769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
17779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
17789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
17799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
17809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
17819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
17829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
17839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
17859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
17869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
17879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
178859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
17899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
17909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
17919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
17929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
17959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
17969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
17979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
17989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
17999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
18009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
18019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
18029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
180559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
180659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
18079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
18089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
18109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
18139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
18149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
18159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
18179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
18189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
18199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
18209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
18219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
18229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
18239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
18269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
18279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
18289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
18299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
18309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
18319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
18339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
18349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
18359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
18379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
18389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
18419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
18429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
18439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
18449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
18459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
18479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
18489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
18499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
18509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
18519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
18529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
18549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
18559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_SCISSOR_TEST);
18569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
18589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
18599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_TEXTURE_2D);
18609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
18619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
18629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
18639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
18649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
18659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
18669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
18679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
18699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
18709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
18729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
18739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
18749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
18769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
18779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
18789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
18829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
18839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
18849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
18859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
188659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
18879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
18889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
18899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
18909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
18919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
18939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
18949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
18959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
18969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
18979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
18989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
18999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
19009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
19019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
19029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
19039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
19049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
19069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
19079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
19089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
19099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
19109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
19119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
19129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
19139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
19149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
19159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
19169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1917a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
1918a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
19199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
19209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
19219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
19229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
19249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
19259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
19269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
19289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
19299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
19309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
19329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
19349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
19359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1936a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
19379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
19389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
19399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
19409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
19419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
19429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
19439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
19449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
194559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
194759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
19489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
19499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
19509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
19529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
19539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
19549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
19579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
19589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
19599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
19629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
19639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
19649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
19659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
196759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
196859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
19709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_SCISSOR_TEST);
19719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
197259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
197359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
19749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
19759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
19769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
19779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
19789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
1979abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
19809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
19819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
19829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
19839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
19849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
19859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
1986abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
1987abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
1988abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
1989abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
1990abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
1991abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
1992abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glDisable(GL_SCISSOR_TEST);
1993abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
1994abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glEnable(GL_SCISSOR_TEST);
1995abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
1996abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
1997015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(false);
1998015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
199959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
200059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
200159119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
200259119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
200359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
200459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2005abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
200659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
200759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2008abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2009abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
201059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
201159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
201259119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
201359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
201459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
201559119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2016abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
201759119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
201959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2021abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
20259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
20279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
20289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2029abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2036abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
20379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
20399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2043abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2044abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2045abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2046015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    hw.setCanDraw(true);
2047a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2048a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2049a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
2050a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    signalEvent();
2051a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2052015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
20579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2059abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2062abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2063abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
20699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2070abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
20719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2075abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
208174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
208274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
208374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2084bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2085bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
208674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
208774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
208874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
208974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
209074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
209174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
209274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
209374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
209474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
209574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
209674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
209774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
209874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
209974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
210074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
210174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if ((sw > hw_w) || (sh > hw_h))
210274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
210374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
210474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
210574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
210674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
210774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
210874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
210974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
211074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
211174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
211274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
211374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
211474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
211574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
211674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
211774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
211874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
211974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
212074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
212274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
212374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
212574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
2126f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian        glScissor(0, 0, sw, sh);
212774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
212874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
212974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
213074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glOrthof(0, hw_w, 0, hw_h, 0, 1);
213174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
213274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
213374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
213474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
213574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2136f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
213774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
213874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        const size_t count = layers.size();
213974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
214074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2141bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            const uint32_t z = layer->drawingState().z;
2142bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            if (z >= minLayerZ && z <= maxLayerZ) {
2143bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                layer->drawForSreenShot();
2144bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
214574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
214674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
214774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // XXX: this is needed on tegra
214874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glScissor(0, 0, sw, sh);
214974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
215074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
215174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
215274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
215374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
215474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
215574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
215674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
215774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
215874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
215974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
216074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
216174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
216274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
216374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
216474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
216574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
216674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
216774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
216874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
216974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
217074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
217174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
217274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glEnable(GL_SCISSOR_TEST);
217574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
217674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
217774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
217874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
217974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
218074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
218274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
218374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
218474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
218574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
218774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
218874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2189e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2190e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2191e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
219474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
219574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
21961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
21971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
219874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2199bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2200bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
22011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
22021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
22031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
22041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
22051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
22081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
22101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
22111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
22121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
22131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
22141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
22151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
221674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2218bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2219bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
22201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
22211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
22221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2224bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2225bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
22261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2227bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2228bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2229bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
22301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
22311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
22331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
22341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
22361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
22371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // if we have secure windows, never allow the screen capture
22391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            if (flinger->mSecureFrameBuffer)
22401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return true;
22411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2243bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
22441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
22461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
22481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2250bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
22511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
22521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
22531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
22541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
22551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
22561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
22571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
22591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2260b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
2261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
2263b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
2264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
2265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
2266b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
22677303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2268b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
226996f0819f81293076e652792794a961543e6750d7Mathias Agopian
2270b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
2271b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
2272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
227596f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
227696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
227796f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
227896f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
227996f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
228096f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
228196f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
228296f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
2283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2285076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
228696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
2287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
229096f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
2291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
229396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
229496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
2295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2297b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
229896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
229996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
230096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
230196f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
230296f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
230396f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
230496f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
230596f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
230696f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
230796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
2308076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
2309076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
231096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
231196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
231296f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
231396f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
2314076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
2315076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
231896f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
2319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
2322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
2323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
232496f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
2325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
233096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
233196f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
233396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
233496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
233696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
233796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
2338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2342b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
2343b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
2344b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2345b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
2346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
2347b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
2349b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
2350b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2351b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
2352b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
2353b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
2354b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2355b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2356b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2357b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
2358b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2359b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
2360b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
2361b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2362b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2363b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
2364b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
2365b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
2366b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
2367b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
2368b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
2369b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
2370b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
2371b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
2372b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
2373b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
2374b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
2375b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2376b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2377b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
2378b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
2379b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2380b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2381b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
2382b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2383b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
2384b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
2385579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
2386579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
2387579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
2388579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
2389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
2390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2392b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
2393b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
2394b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2395b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2396b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
2397b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
2398b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
2399b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
240089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if (layer == 0) {
240189c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis        return name;
240289c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
2403b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2404579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
2405b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
240689c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if ((name >= 0) && (layer->getClient() == this)) {
2407579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
240889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
2409b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2410b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
2411b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
2412b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
2413b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
2414b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
2415579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
2416579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
2417579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
2418579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
2419579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
2420579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
2421579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
2422b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
2423b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
2424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
2425b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
2426b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
2427b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
242853503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
242953503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
2430b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
2431b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2432b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2433b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
2434b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
2435b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
2436b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
2437b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
2438b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
2439b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2440b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
2441b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2442b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2443b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
2444b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
2445b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
2446b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
2447b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
2448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
2450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
2451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
2455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
2456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
2459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
2460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
24632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
24672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
24682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
24692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
24702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
24712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
24722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
24732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
24742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
24752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
24762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
24772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
24782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
24792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
24802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
24812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
24822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
24832b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
24842b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
24852b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
24862b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
24872b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
24882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
24892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
24902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
24912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
24922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
24932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
24942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
24952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
24962b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
24972b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
24982b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
24992b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
25002b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
25012b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25022b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
2507eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
2508eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
2511eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
2512eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
2514eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
2517eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
2518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
2520eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
2524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2525eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
2526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
2530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
25332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
25352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
25362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
25372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
25382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
25392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
25402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
2541eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
2542eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
2543eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
2544eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
2545eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
2546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2547eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
25480d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
25492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
2550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
2551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
255759119e658a12279e8fff508f8773843de2d90917Mathias AgopianDisplayHardware& GraphicPlane::editDisplayHardware() {
255859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return *mHw;
255959119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
256059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2565076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
2566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
2567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
2568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
2569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2572