SurfaceFlinger.cpp revision 35b48d10bc9e064201d3d54d2d476314684a7a05
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24a837ba778f2d7a5170b37aa33624d9b9711c354dJean-Baptiste Queru#include <limits.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/ioctl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
4135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBlur.h"
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBuffer.h"
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian/* ideally AID_GRAPHICS would be in a semi-public header
58a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian * or there would be a way to map a user/group name to its id
59a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian */
60a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#ifndef AID_GRAPHICS
61a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#define AID_GRAPHICS 1003
62a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian#endif
63a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
73cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
76375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
77375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
78375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
83bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
903330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugRegion,       "showupdates enabled");
10978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian    LOGI_IF(mDebugBackground,   "showbackground enabled");
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1247303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1277e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
13096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
13396f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
138b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> bclient;
141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<UserClient> client(new UserClient(this));
142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t err = client->initCheck();
143b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (err == NO_ERROR) {
144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        bclient = client;
145b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
146b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return bclient;
147b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
148b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
149b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
167a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1683330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
169a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1997303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
2007303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
2017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
2027303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
2037303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2047303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
2057303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
2067303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2077303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
2087303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
2242b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->w            = plane.getWidth();
2252b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    dcblk->h            = plane.getHeight();
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_PACK_ALIGNMENT, 4);
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
268a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
269a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
281f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
282f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
2830408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
284f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
285f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
286f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
290f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
291f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
292bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
293f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
294bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
2950408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
2960408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        // see if we timed out
2970408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (isFrozen()) {
2980408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            const nsecs_t now = systemTime();
2990408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            nsecs_t frozenTime = (now - mFreezeDisplayTime);
3000408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            if (frozenTime >= freezeDisplayTimeout) {
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
3040408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
306bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
3070408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            }
3080408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        }
3090408772e34931351d062f2088b611325ddaa6cdbMathias Agopian
3100408772e34931351d062f2088b611325ddaa6cdbMathias Agopian        if (msg != 0) {
3110408772e34931351d062f2088b611325ddaa6cdbMathias Agopian            switch (msg->what) {
3120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                case MessageQueue::INVALIDATE:
3130408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    // invalidate message, just return to the main loop
3140408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                    return;
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
321f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
325f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
326f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
329bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
330bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
332bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return mEventQueue.postMessage(msg, reltime, flags);
333bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
335bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
336bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        nsecs_t reltime, uint32_t flags)
337bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian{
338bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime, flags);
339bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    if (res == NO_ERROR) {
340bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        msg->wait();
341bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
342bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    return res;
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
3738a77baaa11cb90f84d24f345463a856495be81a2Mathias Agopian    if (LIKELY(hw.canDraw() && !isFrozen())) {
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
37535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
37635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        const int index = hw.getCurrentBufferIndex();
37735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        GraphicLog& logger(GraphicLog::getInstance());
37835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
37935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT, index);
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
38335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
38474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
38574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // release the clients before we flip ('cause flip might block)
38735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        postFramebuffer();
39235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
39335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        logger.log(GraphicLog::SF_REPAINT_DONE, index);
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
4069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
4099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
4109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDeferReleaseConsole && hw.canDraw()) {
42662b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (hw.canDraw()) {
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4443d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
4453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4464da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4474da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Perform and commit the transaction
4484da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4494da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
4503d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
4513d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
4529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
4539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
4543d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
4559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
4569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
4574da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian        // here the transaction has been committed
4583d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
4604da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    /*
4614da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * Clean-up all layers that went away
4624da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     * (do this without the lock held)
4634da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian     */
4643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
4653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
4660852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
4670852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
4680852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
4690852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
4703d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
4713d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
4743d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
4753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
4763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
508c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
5162b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->w = plane.getWidth();
5172b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            dcblk->h = plane.getHeight();
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
526064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian            if (mFreezeDisplay)
527064e1e672e62094b32f8cf7a77a3b04c3309dc79Mathias Agopian                 mFreezeDisplayTime = 0;
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5300aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
5310aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
5360aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
5370aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
53848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
5400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
5413d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
5423d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
5430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
5440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
5450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
5463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
5475d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
5480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
5490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
566ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const DisplayHardware& hw(plane.displayHardware());
567ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian    const Region screenRegion(hw.bounds());
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
581970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
583ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
598ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
601ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
604970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
606970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            visibleRegion.andSelf(screenRegion);
609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
611ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
613ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                const int32_t layerOrientation = layer->getOrientation();
617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
619ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
620ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
621ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
628ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
629ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
642a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
650ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
653a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldVisibleRegion = layer->visibleRegionScreen;
656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldCoveredRegion = layer->coveredRegionScreen;
657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
672970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
678970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
679970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
680970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
681970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
690cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
691cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
697000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    LayerVector& currentLayers = const_cast<LayerVector&>(
698000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian            mDrawingState.layersSortedByZ);
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
7064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
7074da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            /*
7084da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             *  rebuild the visible layer list
7094da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian             */
7104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.clear();
7114da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
7124da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            size_t count = currentLayers.size();
7134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            mVisibleLayersSortedByZ.setCapacity(count);
7144da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
7154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
7164da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian                    mVisibleLayersSortedByZ.add(currentLayers[i]);
7174da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian            }
7184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
733b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
744076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
746b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
751b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
754b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
755b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
756b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
757b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
758b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
759b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
765b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
766b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
767b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
768b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
771df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
772df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        (flags & DisplayHardware::BUFFER_PRESERVED))
773df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
77429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
77529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
77629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
77729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
778b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // TODO: we really should be able to pass a region to
77929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
78029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
78129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
78229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
78329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
78429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
78529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
78629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
78895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
78929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
790df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
79195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
79229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
79529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
816000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    const size_t count = layers.size();
817000ca8fa9a1a92aa2f132ba41d11ece6d01cdaddMathias Agopian    for (size_t i=0 ; i<count ; ++i) {
81845721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
81945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        const Region clip(dirty.intersect(layer->visibleRegionScreen));
82045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        if (!clip.isEmpty()) {
82145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            layer->draw(clip);
82245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian        }
82345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    }
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
830076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
832076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8390a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
8400a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
8410a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
8430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            (flags & DisplayHardware::BUFFER_PRESERVED))) {
8440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
8450a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
8460a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        composeSurfaces(repaint);
8470a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
8480a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
8490a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    TextureManager::deactivateTextures();
850df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
8560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
8570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
8580a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
8590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
8600a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
8610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
86420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
86520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
86620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
8760a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
877b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
878b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
879b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
880b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
881b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
8840a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
9040a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glClearColor(0,0,0,0);
90520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
90620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
90720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
90820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
9200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#if defined(GL_OES_texture_external)
9211f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (GLExtensions::getInstance().haveTextureExternal()) {
9221f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
9231f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
9240a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian#endif
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
93120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
93220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
93320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
93420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
960076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
968076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
970f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
9711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
9721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian}
9731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
97496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
97596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
9761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
97796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
97896f0819f81293076e652792794a961543e6750d7Mathias Agopian
97996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
98096f0819f81293076e652792794a961543e6750d7Mathias Agopian    ssize_t name = client->attachLayer(lbc);
98196f0819f81293076e652792794a961543e6750d7Mathias Agopian
98296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
98396f0819f81293076e652792794a961543e6750d7Mathias Agopian    addLayer_l(lbc);
98496f0819f81293076e652792794a961543e6750d7Mathias Agopian
98596f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
98696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
98796f0819f81293076e652792794a961543e6750d7Mathias Agopian
98896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
98996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
99096f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
99196f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
99296f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
99396f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
99496f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
997076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
999b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1000b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (lbc != 0) {
1001b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1002b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1005076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10138c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
10149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
10158c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
10160b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian    layerBase->onRemoved();
10170b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
10183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
10193d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
102096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
102196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
10229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
10239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
102596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102796f0819f81293076e652792794a961543e6750d7Mathias Agopian    layer->forceVisibilityTransaction();
102896f0819f81293076e652792794a961543e6750d7Mathias Agopian    setTransactionFlags(eTraversalNeeded);
102996f0819f81293076e652792794a961543e6750d7Mathias Agopian    return NO_ERROR;
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1037bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1041bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        signalEvent();
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1055cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1056cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // if there is a transaction with a resize, wait for it to
1057cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1058cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1059cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1060448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1061448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1062448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // just in case something goes wrong in SF, return to the
1063448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                // called after a few seconds.
1064448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1065448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                mResizeTransationPending = false;
1066448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian                break;
1067448f015966f367da1791942ffe0b47ae7f9e42caMathias Agopian            }
1068cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
108262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
109662b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1100c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy,
1101c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1109c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112096f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
11217e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
11276e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
11286e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
11296e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
11306e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
11316e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
11326e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
11336e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1135b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> normalLayer;
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
113996f0819f81293076e652792794a961543e6750d7Mathias Agopian                layer = createPushBuffersSurface(client, d, w, h, flags);
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1141b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1142b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                layer = normalLayer;
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
114696f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createBlurSurface(client, d, w, h, flags);
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
114996f0819f81293076e652792794a961543e6750d7Mathias Agopian            layer = createDimSurface(client, d, w, h, flags);
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1153076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
115496f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1155285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
115696f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1157b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
11591c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        if (surfaceHandle != 0) {
116096f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
11611c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
11621c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
11631c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
11641c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
1165b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (normalLayer != 0) {
1166b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                Mutex::Autolock _l(mStateLock);
1167b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1168b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
11691c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1170b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
117196f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1177b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::createNormalSurface(
1178f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
117996f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
11801c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1189a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1190a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1191a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
11928f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1193a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1197a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1198a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1199a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1200a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1201a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
120296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1203f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
120496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (LIKELY(err != NO_ERROR)) {
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1206076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1211b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBlur> SurfaceFlinger::createBlurSurface(
1212f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
121396f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1220b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimSurface(
1221f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
122296f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
122496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1229b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1230f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
123196f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
123896f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
12399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
12409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
12419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
12429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
12430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     *
12440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
12450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
12460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
12479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
12489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
124948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
12500aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
125196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
125248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
125348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
125448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
125548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
125648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
12579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
12589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
12599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
12609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
12619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1263759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
12649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1265f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
12660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1267f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1268f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
12690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
12700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
12710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1272f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1273cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1274cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1275f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1276759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
1277759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * remove the layer from the current list -- chances are that it's
1278759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * not in the list anyway, because it should have been removed
1279759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * already upon request of the client (eg: window manager).
1280759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1281759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1282759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1283759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1284cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
12858c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
12868c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1287f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1288f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1289f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
12903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1291bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    postMessageAsync( new MessageDestroySurface(this, layer) );
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
129696f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
130396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const layer_state_t& s(states[i]);
130496f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1305076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1312f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1314f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.removeAt(idx);
1315f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian                    mCurrentState.layersSortedByZ.add(layer);
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1322cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1324cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1370375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
13779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
13799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
13809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
13819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
13829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
13839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
13849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
13859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
13869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
13879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
13889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
13899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
13909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
13919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
13929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
13939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
13949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE,
13959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
13969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
13979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
13989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
13999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
14031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const sp<LayerBase>& layer(currentLayers[i]);
14041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            layer->dump(result, buffer, SIZE);
14051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            const Layer::State& s(layer->drawingState());
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
14189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
14199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
14209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
14219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
14229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
14231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
14259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
14269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
14279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
14319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
14329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
14339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
14363330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1437076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
14389795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14399795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
14409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
14419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1462a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1463375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1464375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1465375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1466375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1472b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1473375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1474375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1475375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1476375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1477375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1478375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
148301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
148435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1499cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1500cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1501cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1502cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1503cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
150535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1006:{ // enable/disable GraphicLog
150635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                int enabled = data.readInt32();
150735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                GraphicLog::getInstance().setEnabled(enabled);
150835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian                return NO_ERROR;
150935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            }
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
15120408772e34931351d062f2088b611325ddaa6cdbMathias Agopian                mFreezeDisplayTime = 0;
1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
151501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1533b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1535b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> result;
1536b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    Mutex::Autolock _l(mStateLock);
1537b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    result = mLayerMap.valueFor( sur->asBinder() ).promote();
1538b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return result;
1539b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
15407303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
1541b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
154296f0819f81293076e652792794a961543e6750d7Mathias Agopian
1543b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
1544b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mFlinger(flinger), mNameGenerator(1)
1545b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154896f0819f81293076e652792794a961543e6750d7Mathias AgopianClient::~Client()
154996f0819f81293076e652792794a961543e6750d7Mathias Agopian{
155096f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
155196f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
155296f0819f81293076e652792794a961543e6750d7Mathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
155396f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (layer != 0) {
155496f0819f81293076e652792794a961543e6750d7Mathias Agopian            mFlinger->removeLayer(layer);
155596f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
155996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::initCheck() const {
1560b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return NO_ERROR;
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1562076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
156396f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1565b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = android_atomic_inc(&mNameGenerator);
156696f0819f81293076e652792794a961543e6750d7Mathias Agopian    mLayers.add(name, layer);
156796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return name;
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1570b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
157196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
157296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // we do a linear search here, because this doesn't happen often
157396f0819f81293076e652792794a961543e6750d7Mathias Agopian    const size_t count = mLayers.size();
157496f0819f81293076e652792794a961543e6750d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
157596f0819f81293076e652792794a961543e6750d7Mathias Agopian        if (mLayers.valueAt(i) == layer) {
157696f0819f81293076e652792794a961543e6750d7Mathias Agopian            mLayers.removeItemsAt(i, 1);
157796f0819f81293076e652792794a961543e6750d7Mathias Agopian            break;
157896f0819f81293076e652792794a961543e6750d7Mathias Agopian        }
157996f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
158096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
1581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
158396f0819f81293076e652792794a961543e6750d7Mathias Agopian    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
158496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (layer != 0) {
158596f0819f81293076e652792794a961543e6750d7Mathias Agopian        lbc = layer.promote();
158696f0819f81293076e652792794a961543e6750d7Mathias Agopian        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
1587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
159196f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<IMemoryHeap> Client::getControlBlock() const {
1592b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1593b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1594b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
1595b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return -1;
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159796f0819f81293076e652792794a961543e6750d7Mathias Agopiansp<ISurface> Client::createSurface(
1598b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1599b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1600b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
160396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->createSurface(this, pid, name, params,
160496f0819f81293076e652792794a961543e6750d7Mathias Agopian            display, w, h, format, flags);
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160696f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
160796f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->removeSurface(this, sid);
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160996f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t Client::setState(int32_t count, const layer_state_t* states) {
161096f0819f81293076e652792794a961543e6750d7Mathias Agopian    return mFlinger->setClientState(this, count, states);
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1614b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1615b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::UserClient(const sp<SurfaceFlinger>& flinger)
1616b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
1617b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1618b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int pgsize = getpagesize();
1619b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1620b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
1622b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            "SurfaceFlinger Client control-block");
1623b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1624b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1625b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
1626b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        new(ctrlblk) SharedClient;
1627b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1628b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1629b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1630b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianUserClient::~UserClient()
1631b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1632b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (ctrlblk) {
1633b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
1634b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1635b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1636b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    /*
1637b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * When a UserClient dies, it's unclear what to do exactly.
1638b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * We could go ahead and destroy all surfaces linked to that client
1639b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * however, it wouldn't be fair to the main Client
1640b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * (usually the the window-manager), which might want to re-target
1641b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * the layer to another UserClient.
1642b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * I think the best is to do nothing, or not much; in most cases the
1643b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * WM itself will go ahead and clean things up when it detects a client of
1644b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * his has died.
1645b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * The remaining question is what to display? currently we keep
1646b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     * just keep the current buffer.
1647b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian     */
1648b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1649b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1650b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::initCheck() const {
1651b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
1652b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1653b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1654b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianvoid UserClient::detachLayer(const Layer* layer)
1655b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1656b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = layer->getToken();
1657b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (name >= 0) {
1658579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t mask = 1LU<<name;
1659579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
1660579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
1661579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        }
1662b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
1663b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1664b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1665b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<IMemoryHeap> UserClient::getControlBlock() const {
1666b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return mCblkHeap;
1667b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1668b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1669b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
1670b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
1671b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    int32_t name = NAME_NOT_FOUND;
1672b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<Layer> layer(mFlinger->getLayer(sur));
1673b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (layer == 0) return name;
1674b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1675579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    // if this layer already has a token, just return it
1676b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = layer->getToken();
1677579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if ((name >= 0) && (layer->getClient() == this))
1678579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return name;
1679b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1680b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    name = 0;
1681b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    do {
1682b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        int32_t mask = 1LU<<name;
1683b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
1684b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            // we found and locked that name
1685579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            status_t err = layer->setToken(
1686579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    const_cast<UserClient*>(this), ctrlblk, name);
1687579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            if (err != NO_ERROR) {
1688579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                // free the name
1689579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                android_atomic_and(~mask, &mBitmap);
1690579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                name = err;
1691579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            }
1692b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            break;
1693b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
1694b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (++name > 31)
1695b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            name = NO_MEMORY;
1696b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    } while(name >= 0);
1697b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
169853503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
169953503a97a9afa9e876b1e95ca7e3b46c76aa4f15Mathias Agopian    //        sur->asBinder().get(), name, this, mBitmap);
1700b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return name;
1701b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1703b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopiansp<ISurface> UserClient::createSurface(
1704b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        ISurfaceComposerClient::surface_data_t* params, int pid,
1705b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        const String8& name,
1706b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1707b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        uint32_t flags) {
1708b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return 0;
1709b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1710b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::destroySurface(SurfaceID sid) {
1711b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1712b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1713b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianstatus_t UserClient::setState(int32_t count, const layer_state_t* states) {
1714b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return INVALID_OPERATION;
1715b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
1716b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
1717b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17322b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getWidth() const {
17332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mWidth;
1734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint GraphicPlane::getHeight() const {
17372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    return mHeight;
17382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian}
17392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17402b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw)
17412b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
17422b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHw = hw;
17432b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17442b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // initialize the display orientation transform.
17452b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    // it's a constant that should come from the display driver.
17462b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int displayOrientation = ISurfaceComposer::eOrientationDefault;
17472b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    char property[PROPERTY_VALUE_MAX];
17482b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
17492b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        //displayOrientation
17502b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        switch (atoi(property)) {
17512b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 90:
17522b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation90;
17532b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
17542b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        case 270:
17552b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            displayOrientation = ISurfaceComposer::eOrientation270;
17562b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            break;
17572b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        }
17582b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
17592b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17602b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = hw->getWidth();
17612b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = hw->getHeight();
17622b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
17632b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian            &mDisplayTransform);
17642b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
17652b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = h;
17662b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = w;
17672b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    } else {
17682b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayWidth = w;
17692b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian        mDisplayHeight = h;
17702b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    }
17712b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
17722b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    setOrientation(ISurfaceComposer::eOrientationDefault);
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
1777eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian{
1778eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    uint32_t flags = 0;
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
1780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
1781eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_0;
1782eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        break;
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
1784eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_90;
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
1787eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_180;
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
1790eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        flags = Transform::ROT_270;
1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1795eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    tr->set(flags, w, h);
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
18032b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18042b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const DisplayHardware& hw(displayHardware());
18052b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float w = mDisplayWidth;
18062b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    const float h = mDisplayHeight;
18072b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mWidth = int(w);
18082b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mHeight = int(h);
18092b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
18102b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    Transform orientationTransform;
1811eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    GraphicPlane::orientationToTransfrom(orientation, w, h,
1812eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian            &orientationTransform);
1813eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
1814eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mWidth = int(h);
1815eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian        mHeight = int(w);
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1817eda65400f5ae301e26c5f52287d831f063069ec2Mathias Agopian
18180d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
18192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    mGlobalTransform = mDisplayTransform * orientationTransform;
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1831076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
1832076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
1833076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1834076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1838