SurfaceFlinger.cpp revision f6679fc6f70939643901f29a9a69e40c603e6e5f
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
72cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
75375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
82bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
893330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
10878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1217303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1237303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1267e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
12996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
13096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
137b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
166a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1673330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
168a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1987303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
1997303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2007303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_PACK_ALIGNMENT, 4);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
267a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
268a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
280f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
281f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2820408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
283f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
291bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
292f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
293bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2940408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2950408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
2960408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3030408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
305bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3060408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3080408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
320f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
324f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
325f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
329bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
331bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3728a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
37674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
37774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
37874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // release the clients before we flip ('cause flip might block)
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        postFramebuffer();
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
3959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
3969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
3989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
3999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDeferReleaseConsole && hw.canDraw()) {
41562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (hw.canDraw()) {
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4343d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4354da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4364da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4374da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4384da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4393d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4403d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4433d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
4464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4483d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4504da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4524da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4533d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4550852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4560852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4570852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4580852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
497c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
515064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
516064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5240aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5250aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
52748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5290aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5303d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5313d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5353d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5365d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5380aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
555ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
556ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
570970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
576ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
577ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
578ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
579ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
580ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
581ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
582ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
586ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
593970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
595970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
600ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
604ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
605ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
606ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
607ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
631a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
633ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
639ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
642a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
661970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
667970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
668970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
669970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
670970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
679cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
680cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
686b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    LayerVector& currentLayers = const_cast<LayerVector&>(
687b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mDrawingState.layersSortedByZ);
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
6954da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
6964da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
6974da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
6984da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
6994da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7004da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7014da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7024da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7034da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7044da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7054da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
720076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
722b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
735b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
740b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
743b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
744b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
745b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
746b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
747b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
748b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
754b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
755b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
756b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
757b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
760df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
761df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        (flags & DisplayHardware::BUFFER_PRESERVED))
762df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
76329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
76429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
76529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
76629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
767b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
76829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
76929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
77029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
77129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
77229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
77329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
77429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
77529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
77795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
77829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
779df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
78095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
78129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
78429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8044da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
8054da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const size_t count = layers.size();
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
8074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
8084da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
8094da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        if (!clip.isEmpty()) {
8104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            layer->draw(clip);
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
819076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
821076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
8290a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
8300a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8310a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
8320a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
8330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
8340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
8350a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
8360a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
8370a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
839df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
8450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
8460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
8470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
8480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
8490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
8500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
85320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
85420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
85520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8650a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
866b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
867b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
868b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
869b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
870b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
8730a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
8930a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
89420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
89520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
89620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
89720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
9090a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#if defined(GL_OES_texture_external)
9101f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
9111f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
9121f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
9130a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
92020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
92120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
92220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
92320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
949076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
957076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
959f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
9601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
9611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
9621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
96396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
96496f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
9651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
96696f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
96796f0819f81293076e652792794a961543e6750d7Mathias Agopian
96896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
96996f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
97096f0819f81293076e652792794a961543e6750d7Mathias Agopian
97196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
97296f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
97396f0819f81293076e652792794a961543e6750d7Mathias Agopian
97496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
97596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
97696f0819f81293076e652792794a961543e6750d7Mathias Agopian
97796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
97896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
97996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
98096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
98196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
98296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
98396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
986076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
988b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
989b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
990b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
991b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
994076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9973d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10028c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
10039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
10048c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
10050b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
10060b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
10073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
10083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
100996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
101096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
10119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
10129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
101496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101696f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
101796f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
101896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1026bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1030bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1044cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1045cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // if there is a transaction with a resize, wait for it to
1046cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1047cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1048cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1049448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1050448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1051448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1052448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1053448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1054448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1055448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1056448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1057cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
107162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
108562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1089c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy,
1090c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1098c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110996f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
11107e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1114076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
11166e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
11176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
11186e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
11196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
11206e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
11216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
11226e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1124b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
112896f0819f81293076e652792794a961543e6750d7Mathias Agopian                layer = createPushBuffersSurface(client, d, w, h, flags);
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1130b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1131b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                layer = normalLayer;
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
113596f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createBlurSurface(client, d, w, h, flags);
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
113896f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
114396f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1144285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
114596f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
11481c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        if (surfaceHandle != 0) {
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
11501c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
11511c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
11521c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
11531c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1154b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1155b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1156b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
11581c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1159b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
116096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1166b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1167f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
116896f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
11691c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1178a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1179a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1180a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
11818f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1182a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1186a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1187a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1188a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1189a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1190a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
119196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1192f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
119396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1195076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1200b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface(
1201f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
120296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
120496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1209b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1210f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
121196f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1219f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
122096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
122796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
12289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
12299a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
12309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
12319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
12320aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     *
12330aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
12340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
12350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
12369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
12379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
123848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
12390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
124096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
124148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
124248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
124348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
124448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
124548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
12469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
12479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
12489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
12509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1252759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
12539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1254f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
12550aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1256f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1257f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
12580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
12590aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
12600aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1261f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1262cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1263cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1264f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1265759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
1266759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * remove the layer from the current list -- chances are that it's
1267759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * not in the list anyway, because it should have been removed
1268759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * already upon request of the client (eg: window manager).
1269759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1270759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1271759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1272759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1273cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
12748c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
12758c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1276f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1277f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1278f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
12793d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1280bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
128596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
129296f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
129396f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1294076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1301f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1303f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1304f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1311cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1313cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1359375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
13669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
13689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
13699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
13709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
13719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
13729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
13739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
13759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
13769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
13779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
13789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
13799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
13809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
13819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
13829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
13839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE,
13849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
13859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
13869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
13879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
13889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
13921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
13931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
13941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
13991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
14079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
14089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
14099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
14109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
14119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
14121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14139795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
14149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
14159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
14169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
14209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
14219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
14229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14253330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1426076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
14279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
14299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
14309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1451a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1452375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1453375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1454375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1455375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1461b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1462375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1463375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1464375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1465375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1466375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1467375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
147201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1474cbc93ca8005d0a885d54b9a13c18ea07220feedfMathias Agopian            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1489cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1490cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1491cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1492cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1493cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
14970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
150001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1518b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1520b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
1521b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
1522b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
1523b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
1524b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
15257303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
1526b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
152796f0819f81293076e652792794a961543e6750d7Mathias Agopian
1528b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
1529b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
1530b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153396f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
153496f0819f81293076e652792794a961543e6750d7Mathias Agopian{
153596f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
153696f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
153796f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
153896f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
153996f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
154096f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
154496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
1545b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
154896f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1550b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
155196f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
155296f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1555b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
155696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
155796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
155896f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
155996f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
156096f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
156196f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
156296f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
156396f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
156496f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
156596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
1566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
156896f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
156996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
157096f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
157196f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
1572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
157696f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
1577b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1578b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1579b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
1580b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
158296f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
1583b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1584b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1585b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158896f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
158996f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159196f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
159296f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159496f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
159596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1599b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
1601b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
1602b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1603b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
1604b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1605b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1606b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
1607b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
1608b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1609b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1610b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
1611b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
1612b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1613b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1614b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1615b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
1616b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1617b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
1618b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
1619b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1620b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
1622b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
1623b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
1624b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
1625b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
1626b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
1627b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
1628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
1629b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
1630b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
1631b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
1632b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
1633b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1634b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1635b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
1636b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
1637b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1638b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1639b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
1640b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1641b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
1642b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
1643579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
1644579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
1645579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
1646579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
1647b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1648b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1649b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1650b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
1651b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
1652b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1653b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1654b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
1655b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1656b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
1657b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
1658b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (layer == 0) return name;
1659b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1660579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
1661b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
1662579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if ((name >= 0) && (layer->getClient() == this))
1663579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
1664b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1665b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
1666b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
1667b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
1668b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
1669b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
1670579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
1671579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
1672579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
1673579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
1674579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
1675579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
1676579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
1677b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
1678b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
1679b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
1680b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
1681b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
1682b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
168353503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
168453503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
1685b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
1686b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1687b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1688b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
1689b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1690b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1691b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1692b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
1693b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1694b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1695b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
1696b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1697b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1698b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
1699b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1700b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1701b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
1710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
17182b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
17222b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
17232b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
17242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
17262b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
17272b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
17282b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17292b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
17302b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
17312b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
17322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
17332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
17342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
17352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
17362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
17372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
17382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
17392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
17402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
17412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
17422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
17432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
17442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
17462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
17472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
17482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
17492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
17502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
17512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
17522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
17532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
17542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
17552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
17562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
1761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
1762eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
1763eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
1766eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
1767eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
1769eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
1772eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
1775eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1780eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
17882b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17892b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
17902b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
17912b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
17922b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
17932b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
17942b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17952b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
1796eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
1797eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
1798eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
1799eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
1800eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1802eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
18030d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
18042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
1809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1816076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
1817076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
1818076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1819076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1823