SurfaceFlinger.cpp revision 24925bfba22ac24de8dedc8f2c1cad5be7ade14f
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>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
55a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
73cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
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),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
84bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
913330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
11078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1237303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1287e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13496f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
149b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
150b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
168a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1693330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
170a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2007303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2097303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_PACK_ALIGNMENT, 4);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
269a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
282f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2840408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
293bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
295bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2960408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3050408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
307bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3080408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
322f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
326f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
327f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
330bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
373a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
374a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
375a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
376a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
377a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3798a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
38474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
38574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // release the clients before we flip ('cause flip might block)
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        postFramebuffer();
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDeferReleaseConsole && hw.canDraw()) {
42262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (hw.canDraw()) {
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4403d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4413d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4424da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4444da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4454da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
453a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty = true;
4544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4584da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4594da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
461a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4640852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4650852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4660852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4670852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4683d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4723d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4743d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
485076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
506c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
524064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
525064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5280aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5290aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
53648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5393d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5403d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5443d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5455d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
564ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
565ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
579970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
581ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
582ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
583ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
586ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
602970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
604970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
640a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
651a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
676970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
677970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
678970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
679970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
688cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
689cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
695a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    LayerVector& currentLayers(
696a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7044da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7054da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7084da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7094da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
719a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            mHwWorkListDirty = true;
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
732b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
745b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
750a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
751a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
752a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
753a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
754a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
755a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
756a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
757a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
75845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
75945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
76045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
761a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
762a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
763a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
764b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
767b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
768b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
769b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
770b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
771b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
772b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
778b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
779b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
780b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
781b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
784df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
785df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        (flags & DisplayHardware::BUFFER_PRESERVED))
786df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
78729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
78829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
78929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
79029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
79229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
79329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
79429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
79529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
79629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
79729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
79829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
79929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
80195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
80229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
803df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
80495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
80529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
828a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
829a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    status_t err = NO_ERROR;
8304da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
83145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
832a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
833a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
834a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(hw.getHwComposer());
83545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
836a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
83745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    LOGE_IF(cur && hwc.getNumLayers() != count,
83845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
83945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
840a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
84145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
84224925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
84324925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
84424925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
845a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
84645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
84745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
84845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
84945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
85045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    Region transparent;
85145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    if (cur) {
85245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
85345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
85445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->setPerFrameData(&cur[i]);
85545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            if (cur[i].hints & HWC_HINT_CLEAR_FB) {
85645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                if (!(layer->needsBlending())) {
85745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
85845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                }
859a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            }
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        err = hwc.prepare();
86245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
864a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
86545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  clear the area of the FB that need to be transparent
86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
868a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    transparent.andSelf(dirty);
869a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (!transparent.isEmpty()) {
870a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        glClearColor(0,0,0,0);
871a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator it = transparent.begin();
872a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator const end = transparent.end();
873a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const int32_t height = hw.getHeight();
874a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        while (it != end) {
875a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const Rect& r(*it++);
876a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const GLint sy = height - (r.top + r.height());
877a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glScissor(r.left, sy, r.width(), r.height());
878a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
880a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
88145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
88245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
88345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
88445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
88545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
88645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
88745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (cur) {
88845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
88945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                    cur[i].flags & HWC_SKIP_LAYER) {
89045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                // skip layers handled by the HAL
89145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                continue;
89245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            }
89345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
89445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
89545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
89845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
89945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
906076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
908076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9150a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9160a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
9170a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9180a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9190a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9210a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9220a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9230a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9250a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
926df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
9370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
93920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
94020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
94120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
94220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
953b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
954b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
955b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
956b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
957b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
9600a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
9800a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
98120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
98220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
98320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
98420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
9960a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#if defined(GL_OES_texture_external)
9971f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
9981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
9991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
10000a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
100720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
100820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
100920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
101020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1036076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1044076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1046f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
10471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
10481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
10491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
105096f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
105196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
10521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
105396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
105496f0819f81293076e652792794a961543e6750d7Mathias Agopian
105596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
105696f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
105796f0819f81293076e652792794a961543e6750d7Mathias Agopian
105896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
105996f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
106096f0819f81293076e652792794a961543e6750d7Mathias Agopian
106196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
106296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
106396f0819f81293076e652792794a961543e6750d7Mathias Agopian
106496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
106596f0819f81293076e652792794a961543e6750d7Mathias Agopian{
106696f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
106796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
106896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
106996f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
107096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1075b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1076b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1077b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1078b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1081076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10879a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10898c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
10909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
10918c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
10920b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
10930b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
10943d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
10953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
109696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
109796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
10989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
10999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
110196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
110396f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
110496f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
110596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1113bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1117bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1131cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1132cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // if there is a transaction with a resize, wait for it to
1133cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1134cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1135cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1136448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1137448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1138448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1139448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1140448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1141448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1142448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1143448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
115862b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
117262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1176c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy,
1177c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1185c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
11977e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1201076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
12036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12046e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12086e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12096e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1211b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
121596f0819f81293076e652792794a961543e6750d7Mathias Agopian                layer = createPushBuffersSurface(client, d, w, h, flags);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1217b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1218b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                layer = normalLayer;
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
122296f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createBlurSurface(client, d, w, h, flags);
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
122596f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1229076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
123096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1231285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
123296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1233b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12351c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        if (surfaceHandle != 0) {
123696f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
12371c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
12381c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
12391c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
12401c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1241b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1242b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1243b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1244b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12451c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1246b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
124796f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1254f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
125596f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12561c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1265a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1266a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1267a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
12688f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1269a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1273a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1274a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1275a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1276a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1277a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
127896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1279f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
128096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1282076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface(
1288f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
128996f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
129196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
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
1305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1306f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
130796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
130996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     *
13200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13210aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13220aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
132548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
132796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
132848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
132948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
133048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
133148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
133248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
13379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1339759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
13409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1341f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
13420aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1343f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1344f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
13450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
13460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
13470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1348f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1349cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1350cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1351f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1352759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
1353759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * remove the layer from the current list -- chances are that it's
1354759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * not in the list anyway, because it should have been removed
1355759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * already upon request of the client (eg: window manager).
1356759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1357759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1358759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1359759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1360cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
13618c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
13628c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1363f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1364f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1365f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
13663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1367bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
137296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
137996f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
138096f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1381076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1388f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1390f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1391f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1398cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1400cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1401cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1446375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14549795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14589795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE,
14719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
14791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
14801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
14811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
14959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
14969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
14979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
14989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
14991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15123330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1538a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1539375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1540375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1541375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1542375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1548b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1549375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1550375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1551375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1552375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1553375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1554375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
155901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1561cbc93ca8005d0a885d54b9a13c18ea07220feedfMathias Agopian            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1577cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
15840408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
158701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1605b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1607b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
1608b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
1609b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
1610b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
1611b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
16127303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
1613b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
161496f0819f81293076e652792794a961543e6750d7Mathias Agopian
1615b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
1616b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
1617b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162096f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
162196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
162296f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
162396f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
162496f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
162596f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
162696f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
162796f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
163196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
1632b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1634076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
163596f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1637b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
163896f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
163996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1642b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
164396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
164496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
164596f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
164696f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
164796f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
164896f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
164996f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
165096f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
165196f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
165296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
1653076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1654076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
165596f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
165696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
165796f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
165896f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
1659076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1660076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166396f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
1664b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1665b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1666b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
1667b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
166996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
1670b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1671b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1672b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
167596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
167696f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
167896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
167996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
168196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
168296f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1686b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1687b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
1688b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
1689b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1690b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
1691b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1692b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1693b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
1694b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
1695b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1696b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1697b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
1698b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
1699b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1700b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1701b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
1703b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1704b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
1705b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
1706b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1707b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1708b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
1709b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
1710b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
1711b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
1712b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
1713b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
1714b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
1715b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
1716b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
1717b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
1718b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
1719b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
1720b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1721b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1722b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
1723b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
1724b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1725b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1726b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
1727b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1728b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
1729b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
1730579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
1731579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
1732579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
1733579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
1734b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1735b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
1738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
1739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1740b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
1742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1743b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
1744b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
1745b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (layer == 0) return name;
1746b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1747579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
1748b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
1749579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if ((name >= 0) && (layer->getClient() == this))
1750579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
1751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
1753b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
1754b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
1755b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
1756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
1757579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
1758579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
1759579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
1760579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
1761579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
1762579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
1763579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
1764b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
1765b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
1766b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
1767b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
1768b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
1769b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
177053503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
177153503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
1772b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
1773b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1774b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1775b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
1776b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1777b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1778b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1779b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
1780b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1781b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1782b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
1783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1784b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1785b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
1786b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1787b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1788b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1789b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
18052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
18092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
18102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
18112b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18122b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
18132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
18142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
18152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
18172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
18182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
18192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
18202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
18212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
18222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
18232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
18242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
18252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
18262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
18272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
18282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
18292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
18302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
18312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
18332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
18342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
18352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
18362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
18372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
18382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
18392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
18402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
18412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
18422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
18432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
1849eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
1850eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
1852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
1853eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
1854eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
1855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
1856eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
1857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
1859eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
1860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
1862eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1867eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
18752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
18772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
18782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
18792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
18802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
18812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
1883eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
1884eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
1885eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
1886eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
1887eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1889eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
18900d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
18912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
1901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1903076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
1904076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
1905076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1906076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1910