SurfaceFlinger.cpp revision 8372785879d329f592f6883620b5a32d80d74691
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
56a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
64a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
74cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
78375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
79375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
81a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
85bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
8873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
933330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
11278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1277303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1307e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
13396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
13496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13696f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
149b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
150b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
151b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
152b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
1708b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1713330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
172a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2107303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2117303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
270a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
271a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
2728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2860408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
294f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
295bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
296f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
297bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
3010408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
3020408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3030408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
309bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3150408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3160408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3170408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
328f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
329f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
343bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
344bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
345bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
375a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (UNLIKELY(mHwWorkListDirty)) {
376a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        // build the h/w work list
377a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        handleWorkList();
378a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
379a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3818a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
38335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
38535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
38635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
38735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
39135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
39274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
39374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
39435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
3958392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala        postFramebuffer();
3968392b504bdf63ac7820c79c7217a89f2b2411bd0Antti Hatala
397c479e18db0216f7096fefe85ffa71ab00329aef3Mathias Agopian        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDeferReleaseConsole && hw.canDraw()) {
43362b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (hw.canDraw()) {
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4534da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4544da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4554da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4564da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4573d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4583d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4613d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
464a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty = true;
4654da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4673d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4684da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4694da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4704da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4714da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
472a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4743d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4750852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4760852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4770852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4780852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4853d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
517c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
535064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
536064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
54748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5540aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5565d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
575ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
576ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
590970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
613970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
615970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
651a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
662a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
6768b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
681970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
687970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
688970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
689970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
690970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
699cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
700cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
706a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    LayerVector& currentLayers(
707a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7194da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7204da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7214da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7224da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7234da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7244da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7264da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7274da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
730a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            mHwWorkListDirty = true;
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
743b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
754076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
761a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid SurfaceFlinger::handleWorkList()
762a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
763a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
764a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
765a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
766a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
767a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
768a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
76945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        hwc_layer_t* const cur(hwc.getLayers());
77045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; cur && i<count ; i++) {
77145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            currentLayers[i]->setGeometry(&cur[i]);
77273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            if (mDebugDisableHWC) {
77373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].compositionType = HWC_FRAMEBUFFER;
77473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                cur[i].flags |= HWC_SKIP_LAYER;
77573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
776a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
777a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
778a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
779b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
782b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
783b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
784b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
785b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
786b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
787b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
794b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
795b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
796b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
7998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
8008b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        (flags & DisplayHardware::BUFFER_PRESERVED))
801df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
80229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
80329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
80429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
80529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
806b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
80729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
80829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
80929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
81029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
81129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
81229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
81329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
81429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
81695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
81729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
818df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
81995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
82029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
82329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
843a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
844a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    status_t err = NO_ERROR;
8454da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
84645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
847a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
848a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
849a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    HWComposer& hwc(hw.getHwComposer());
85045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    hwc_layer_t* const cur(hwc.getLayers());
851a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
85245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    LOGE_IF(cur && hwc.getNumLayers() != count,
85345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
85445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
855a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
85645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
85724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
85824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
85924925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
860a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
86145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
86245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
86345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
86445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
86545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    Region transparent;
86645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    if (cur) {
86745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
86845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
86945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->setPerFrameData(&cur[i]);
87045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            if (cur[i].hints & HWC_HINT_CLEAR_FB) {
87145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                if (!(layer->needsBlending())) {
87245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                    transparent.orSelf(layer->visibleRegionScreen);
87345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                }
874a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            }
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
87645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        err = hwc.prepare();
87745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
879a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
88045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
88145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  clear the area of the FB that need to be transparent
88245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
883a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    transparent.andSelf(dirty);
884a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (!transparent.isEmpty()) {
885a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        glClearColor(0,0,0,0);
886a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator it = transparent.begin();
887a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        Region::const_iterator const end = transparent.end();
888a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const int32_t height = hw.getHeight();
889a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        while (it != end) {
890a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const Rect& r(*it++);
891a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            const GLint sy = height - (r.top + r.height());
892a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glScissor(r.left, sy, r.width(), r.height());
893a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
894a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
895a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
89645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
89745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
89845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
89945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     * and then, render the layers targeted at the framebuffer
90045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
90145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
90245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (cur) {
903586a0deb76012c4347298c11df460631853b67f8Antti Hatala            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
904586a0deb76012c4347298c11df460631853b67f8Antti Hatala                !(cur[i].flags & HWC_SKIP_LAYER)) {
90545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                // skip layers handled by the HAL
90645721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian                continue;
90745721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            }
90845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
90973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
91045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
91145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
91245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
91345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
91445721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
91545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
922076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
924076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
9320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
9330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
9350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
9360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
9380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
9390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
9400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
9410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
942df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9500a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
9510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9520a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
9530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
95620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
95720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
95820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9680a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
969b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
970b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
971b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
972b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
973b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
9760a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
9960a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
99720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
99820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
99920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
100020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
10127f198b6bff54af3c8e8ac32b83ffc6488e773ac1Michael I. Gold#if defined(GL_OES_EGL_image_external)
10131f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
10141f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
10151f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
10160a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
102320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
102420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
102520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
102620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1052076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1060076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1062f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
10631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
10641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
10651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
106696f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
106796f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
10681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
106996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
107096f0819f81293076e652792794a961543e6750d7Mathias Agopian
107196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
107296f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
107396f0819f81293076e652792794a961543e6750d7Mathias Agopian
107496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
107596f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
107696f0819f81293076e652792794a961543e6750d7Mathias Agopian
107796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
107896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
107996f0819f81293076e652792794a961543e6750d7Mathias Agopian
108096f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
108196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
108296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
108396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
108496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
108596f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
108696f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1089076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1091b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1092b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1093b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1094b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1097076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11003d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
11049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
11058c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
11069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
11078c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
11080b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
11090b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
11103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
11113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
111296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
111396f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
11149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
11159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
11169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
111796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
111996f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
112096f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
112196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1129bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1133bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1147cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
11488b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        // if there is a transaction with a resize, wait for it to
1149cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1150cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1151cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1152448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1153448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1154448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1155448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1156448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1157448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1158448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1159448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1160cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
117462b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
118862b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11928b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huberint SurfaceFlinger::setOrientation(DisplayID dpy,
1193c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1201c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121296f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
12137e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1217076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
12196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12206e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12226e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12246e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1227b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
12308b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber#if HAS_PUSH_BUFFERS
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
123296f0819f81293076e652792794a961543e6750d7Mathias Agopian                layer = createPushBuffersSurface(client, d, w, h, flags);
12338b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            } else
12348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber#endif
12358b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            {
1236b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1237b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                layer = normalLayer;
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
124196f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createBlurSurface(client, d, w, h, flags);
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
124496f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1248076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
124996f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1250285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
125196f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1252b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12548b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
125596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
12561c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
12571c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
12581c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
12591c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1260b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1261b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1262b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1263b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
12641c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1265b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
126696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1272b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1273f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
127496f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
12751c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1284a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1285a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1286a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
12878f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1288a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1292a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1293a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1294a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1295a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1296a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
129796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1298f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
129996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1301076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface(
1307f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
130896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1316f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
131796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
131996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1324b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1325f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
132696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
133396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
13349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13388b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
13390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13439a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
134448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
134696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
134748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
134848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
134948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
135048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
135148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
13569a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1358759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
13598b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1360f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
13610aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1362f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1363f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
13640aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
13650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
13660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1367f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1368cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1369cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1370f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1371759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
13728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * remove the layer from the current list -- chances are that it's
13738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * not in the list anyway, because it should have been removed
13748b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber             * already upon request of the client (eg: window manager).
1375759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1376759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1377759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1378759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1379cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
13808c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
13818c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1382f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1383f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1384f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
13853d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1386bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
139196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
139896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
139996f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1400076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1407f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1409f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1410f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1420cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1465375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14898b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
14909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
14981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
14991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
15001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
15159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
15169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
15179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
15259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
153173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        HWComposer& hwc(hw.getHwComposer());
153273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
153373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                hwc.initCheck()==NO_ERROR ? "present" : "not present",
153473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC ? "disabled" : "enabled");
153573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        result.append(buffer);
15368372785879d329f592f6883620b5a32d80d74691Mathias Agopian        hwc.dump(result, buffer, SIZE);
153773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
15383330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1564a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1565375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1566375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1567375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1568375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1574b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1575375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1576375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1577375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1578375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1579375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1580375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
158501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
158635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
159673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            case 1008:  // toggle use of hw composer
159773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                n = data.readInt32();
159873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mDebugDisableHWC = n ? 1 : 0;
159973d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                mHwWorkListDirty = true;
160073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian                // fall-through...
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1606cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1607cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1608cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1609cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1610cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
161235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
161335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
161435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
161535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
161635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
16190408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
162201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1640b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1642b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
1643b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
1644b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
1645b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
1646b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
16477303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
1648b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
164996f0819f81293076e652792794a961543e6750d7Mathias Agopian
1650b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
1651b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
1652b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165596f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
165696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
165796f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
165896f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
165996f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
166096f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
166196f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
166296f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1665076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
166696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
1667b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1669076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
167096f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1672b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
167396f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
167496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1677b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
167896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
167996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
168096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
168196f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
168296f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
168396f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
168496f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
168596f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
168696f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
168796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
1688076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1689076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
169096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
169196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
169296f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
169396f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
1694076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
169896f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
1699b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1700b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1701b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
1702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
170496f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
1705b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1706b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1707b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
171096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
171196f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171396f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
171496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
171796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1721b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1722b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
1723b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
1724b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1725b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
1726b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1727b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1728b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
1729b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
1730b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1731b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1732b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
1733b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
1734b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1735b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1736b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1737b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
1738b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1739b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
1740b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
1741b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1742b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1743b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
1744b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
1745b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
1746b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
1747b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
1748b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
1749b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
1750b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
1751b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
1752b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
1753b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
1754b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
1755b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1756b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1757b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
1758b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
1759b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1761b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
1762b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1763b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
1764b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
1765579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
1766579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
1767579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
1768579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
1769b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1770b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1771b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1772b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
1773b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
1774b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1775b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1776b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
1777b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1778b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
1779b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
178089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if (layer == 0) {
178189c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis        return name;
178289c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
1783b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1784579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
1785b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
178689c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    if ((name >= 0) && (layer->getClient() == this)) {
1787579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
178889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    }
1789b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1790b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
1791b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
1792b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
1793b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
1794b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
1795579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
1796579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
1797579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
1798579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
1799579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
1800579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
1801579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
1802b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
1803b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
1804b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
1805b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
1806b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
1807b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
180853503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
180953503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
1810b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
1811b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1812b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1813b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
1814b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1815b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1816b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1817b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
1818b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1819b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1820b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
1821b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1822b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1823b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
1824b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1825b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1826b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1827b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
1831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
1836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
1840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
18432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
18472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
18482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
18492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
18512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
18522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
18532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
18552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
18562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
18572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
18582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
18592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
18602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
18612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
18622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
18632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
18642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
18652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
18662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
18672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
18682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
18692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
18712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
18722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
18732b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
18742b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
18752b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
18762b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
18772b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
18782b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
18792b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
18802b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
18812b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18822b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
1887eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
1888eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
1891eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
1892eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
1894eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
1897eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
1900eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
1901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1905eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
1906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
19132b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
19142b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
19152b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
19162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
19172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
19182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
19192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
19202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
1921eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
1922eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
1923eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
1924eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
1925eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1927eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
19280d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
19292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
1935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1941076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
1942076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
1943076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1944076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1948