SurfaceFlinger.cpp revision 95a666b0e001ebf738418b89d8e8fd50b18110f8
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
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/DisplayInfo.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <pixelflinger/pixelflinger.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
47cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include "Buffer.h"
48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include "BufferAllocator.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 Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::instantiate() {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    defaultServiceManager()->addService(
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String16("SurfaceFlinger"), new SurfaceFlinger());
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::shutdown() {
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we should unregister here, but not really because
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // when (if) the service manager goes away, all the services
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // it has a reference to will leave too.
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : lookup(rhs.lookup), layers(rhs.layers)
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceFlinger::LayerVector::indexOf(
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& key, size_t guess) const
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (guess<size() && lookup.keyAt(guess) == key)
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return guess;
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t i = lookup.indexOfKey(key);
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (i>=0) {
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t idx = lookup.valueAt(i);
96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE_IF(layers[idx]!=key,
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "LayerVector[%p]: layers[%d]=%p, key=%p",
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            this, int(idx), layers[idx].get(), key.get());
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return idx;
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return i;
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceFlinger::LayerVector::add(
105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer,
106076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        Vector< sp<LayerBase> >::compar_t cmp)
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = layers.size();
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t l = 0;
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t h = count-1;
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t mid;
112076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* a = layers.array();
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (l <= h) {
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mid = l + (h - l)/2;
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int c = cmp(a+mid, &layer);
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (c == 0)     { l = mid; break; }
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (c<0)   { l = mid+1; }
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else            { h = mid-1; }
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t order = l;
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (order<count && !cmp(&layer, a+order)) {
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        order++;
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    count = lookup.size();
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (lookup.valueAt(i) >= order) {
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            lookup.editValueAt(i)++;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layers.insertAt(layer, order);
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    lookup.add(layer, order);
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return order;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t keyIndex = lookup.indexOfKey(layer);
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (keyIndex >= 0) {
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t index = lookup.valueAt(keyIndex);
140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE_IF(layers[index]!=layer,
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "LayerVector[%p]: layers[%u]=%p, layer=%p",
142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                this, int(index), layers[index].get(), layer.get());
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layers.removeItemsAt(index);
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        lookup.removeItemsAt(keyIndex);
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = lookup.size();
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (lookup.valueAt(i) >= size_t(index)) {
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                lookup.editValueAt(i)--;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return index;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NAME_NOT_FOUND;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceFlinger::LayerVector::reorder(
157076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer,
158076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        Vector< sp<LayerBase> >::compar_t cmp)
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: it's a little lame. but oh well...
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t err = remove(layer);
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err >=0)
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        err = add(layer, cmp);
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionCount(0),
176cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mResizeTransationPending(false),
177076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
179375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mHardwareTest("android.permission.HARDWARE_TEST"),
180375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
181375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        mDump("android.permission.DUMP"),
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole(false),
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeDisplay(false),
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFreezeCount(0),
186bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        mFreezeDisplayTime(0),
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugBackground(0),
1899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mConsoleSignals(0),
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSecureFrameBuffer(0)
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init();
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::init()
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("SurfaceFlinger is starting");
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showbackground", value, "0");
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugBackground = atoi(value);
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI_IF(mDebugRegion,           "showupdates enabled");
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI_IF(mDebugBackground,       "showbackground enabled");
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return graphicPlane(0).displayHardware().getOverlayEngine();
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2247303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2267303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t token = mTokens.acquire();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
234f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client = new Client(token, this);
235f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (client->ctrlblk == 0) {
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTokens.release(token);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = mClientsMap.add(token, client);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err < 0) {
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTokens.release(token);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<BClient> bclient =
2457303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian        new BClient(this, token, client->getControlBlockMemory());
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::destroyConnection(ClientID cid)
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
252f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client = mClientsMap.valueFor(cid);
253f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (client != 0) {
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // free all the layers this client owns
2553d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Vector< wp<LayerBaseClient> > layers(client->getLayers());
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = layers.size();
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
258076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            sp<LayerBaseClient> layer(layers[i].promote());
259076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (layer != 0) {
2603d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                purgatorizeLayer_l(layer);
261076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the resources associated with this client will be freed
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // during the next transaction, after these surfaces have been
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // properly removed from the screen
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // remove this client from our ClientID->Client mapping.
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mClientsMap.removeItem(cid);
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // and add it to the list of disconnected clients
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDisconnectedClients.add(client);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // request a transaction
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(eTransactionNeeded);
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(mGraphicPlanes[dpy]);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return plane;
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return const_cast<GraphicPlane&>(
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
296a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
297a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.stop", "bootanim");
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::onFirstRef()
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Wait for the main thread to be done with its initialization
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.wait();
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint16_t pack565(int r, int g, int b) {
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (r<<11)|(g<<5)|b;
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::readyToRun()
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI(   "SurfaceFlinger's main thread ready to run. "
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "Initializing graphics H/W...");
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we only support one display currently
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int dpy = 0;
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // initialize the main display
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane& plane(graphicPlane(dpy));
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayHardware* const hw = new DisplayHardware(this, dpy);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        plane.setDisplayHardware(hw);
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3277303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    // create the shared control-block
3287303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
3297303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
3307303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
3317303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
3337303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
3347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
3367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize primary screen
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (other display should be initialized in the same manner, but
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // asynchronously, as they could come and go. None of this is supported
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // yet).
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(dpy));
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = plane.displayHardware();
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t w = hw.getWidth();
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t h = hw.getHeight();
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t f = hw.getFormat();
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    hw.makeCurrent();
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the shared control block
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mServerCblk->connected |= 1<<dpy;
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    display_cblk_t* dcblk = mServerCblk->displays + dpy;
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    memset(dcblk, 0, sizeof(display_cblk_t));
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->w            = w;
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->h            = h;
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->format       = f;
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->xdpi         = hw.getDpiX();
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->ydpi         = hw.getDpiY();
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->fps          = hw.getRefreshRate();
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dcblk->density      = hw.getDensity();
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    asm volatile ("":::"memory");
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Initialize OpenGL|ES
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glActiveTexture(GL_TEXTURE0);
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, 0);
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_PACK_ALIGNMENT, 4);
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t textureData[4] = { g0, g1, g1, g0 };
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glOrthof(0, w, h, 0, 0, 1);
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   LayerDim::initDimmer(this, w, h);
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mReadyToRunBarrier.open();
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *  We're now ready to accept clients...
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
404a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    property_set("ctl.start", "bootanim");
405a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Events Handler
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::waitForEvent()
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
417f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    while (true) {
418f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        nsecs_t timeout = -1;
419f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (UNLIKELY(isFrozen())) {
420f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // wait 5 seconds
421f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t freezeDisplayTimeout = ms2ns(5000);
422f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            const nsecs_t now = systemTime();
423f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            if (mFreezeDisplayTime == 0) {
424f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                mFreezeDisplayTime = now;
425f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
426f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
427f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            timeout = waitTime>0 ? waitTime : 0;
428bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project        }
429f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
430b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian        MessageList::value_type msg = mEventQueue.waitMessage(timeout);
431f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        if (msg != 0) {
432f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            mFreezeDisplayTime = 0;
433f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            switch (msg->what) {
434f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                case MessageQueue::INVALIDATE:
435f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                    // invalidate message, just return to the main loop
436f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                    return;
437f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            }
438f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        } else {
439f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            // we timed out
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (isFrozen()) {
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // we timed out and are still frozen
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        mFreezeDisplay, mFreezeCount);
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = 0;
445bcef13b666c7459241235bc6209837ae81884d2fThe Android Open Source Project                mFreezeDisplay = false;
446f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian                return;
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalEvent() {
453f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.invalidate();
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signal() const {
457f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    // this is the IPC call
458f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    const_cast<SurfaceFlinger*>(this)->signalEvent();
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
463f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark Main loop
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::threadLoop()
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // check for transactions
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mConsoleSignals)) {
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleConsoleEvents();
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mTransactionCount == 0)) {
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if we're in a global transaction, don't do anything.
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t transactionFlags = getTransactionFlags(mask);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(transactionFlags)) {
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            handleTransaction(transactionFlags);
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // post surfaces (if needed)
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    handlePageFlip();
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(hw.canDraw())) {
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // repaint the framebuffer (if needed)
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        handleRepaint();
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        // inform the h/w that we're done compositing
49974faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        hw.compositionComplete();
50074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // release the clients before we flip ('cause flip might block)
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        postFramebuffer();
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // pretend we did the post
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        unlockClients();
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        usleep(16667); // 60 fps period
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return true;
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5150926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (isFrozen()) {
5160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        // we are not allowed to draw, but pause a bit to make sure
5170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        // apps don't end up using the whole CPU, if they depend on
5180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        // surfaceflinger for synchronization.
5190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        usleep(8333); // 8.3ms ~ 120fps
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!mInvalidRegion.isEmpty()) {
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
5259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
5269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = now;
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.flip(mInvalidRegion);
5289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime = systemTime() - now;
5299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers = 0;
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mInvalidRegion.clear();
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleConsoleEvents()
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // something to do with the console
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw = graphicPlane(0).displayHardware();
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int what = android_atomic_and(0, &mConsoleSignals);
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleAcquired) {
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.acquireScreen();
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDeferReleaseConsole && hw.canDraw()) {
54562b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // We got the release signal before the acquire signal
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDeferReleaseConsole = false;
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        hw.releaseScreen();
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (what & eConsoleReleased) {
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (hw.canDraw()) {
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hw.releaseScreen();
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDeferReleaseConsole = true;
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.set(hw.bounds());
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    Vector< sp<LayerBase> > ditchedLayers;
5643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
5653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    { // scope for the lock
5663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        Mutex::Autolock _l(mStateLock);
5679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
5689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = now;
5693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        handleTransactionLocked(transactionFlags, ditchedLayers);
5709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime = systemTime() - now;
5719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction = 0;
5723d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
5733d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
5743d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // do this without lock held
5753d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const size_t count = ditchedLayers.size();
5763d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
5770852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        if (ditchedLayers[i] != 0) {
5780852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            //LOGD("ditching layer %p", ditchedLayers[i].get());
5790852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian            ditchedLayers[i]->ditch();
5800852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        }
5813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    }
5823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5843d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(
5853d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
5863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
5873d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eRestartTransaction) {
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // restart the transaction, but back-off a little
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                layer->setTransactionFlags(eTransactionNeeded);
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                setTransactionFlags(eTraversalNeeded, ms2ns(8));
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int dpy = 0;
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int orientation = mCurrentState.orientation;
625c08731e756868653d09d3e49b723706df3687070Mathias Agopian            const uint32_t type = mCurrentState.orientationType;
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            GraphicPlane& plane(graphicPlane(dpy));
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            plane.setOrientation(orientation);
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // update the shared control block
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const DisplayHardware& hw(plane.displayHardware());
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dcblk->orientation = orientation;
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (orientation & eOrientationSwapMask) {
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // 90 or 270 degrees orientation
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                dcblk->w = hw.getHeight();
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                dcblk->h = hw.getWidth();
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                dcblk->w = hw.getWidth();
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                dcblk->h = hw.getHeight();
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
644c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mFreezeDisplayTime = 0;
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // freezing or unfreezing the display -> trigger animation if needed
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFreezeDisplay = mCurrentState.freezeDisplay;
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6520aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
6530aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
6580aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
6590aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
66048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
6620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
6633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
6643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
6650aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
6660aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
6670aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
6683d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian                    ditchedLayers.add(layer);
6695d7126b625c8c4a7b945e8c247b63abff7bc13b6Mathias Agopian                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
6700aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
6710aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // get rid of all resources we don't need anymore
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // (layers and clients)
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        free_resources_l();
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<FreezeLock> SurfaceFlinger::getFreezeLock() const
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool secureFrameBuffer = false;
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
701076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->validateVisibility(planeTransform);
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
705970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // handle hidden surfaces by setting the visible region to empty
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
711970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const bool translucent = layer->needsBlending();
713970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian            const Rect bounds(layer->visibleBounds());
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            coveredRegion = visibleRegion;
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Remove the transparent area from the visible region
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (translucent) {
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                visibleRegion.subtractSelf(layer->transparentRegionScreen);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // compute the opaque region
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // the opaque region is the visible region
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                opaqueRegion = visibleRegion;
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        coveredRegion.andSelf(aboveCoveredLayers);
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty.orSelf(layer->visibleRegionScreen);
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
741a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
742a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             *    exposed = what's VISIBLE and NOT COVERED now
743a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             *    but was COVERED before
744a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
745a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75262b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian        // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
754a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
760970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        // If a secure layer is partially visible, lock-down the screen!
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->isSecure() && !visibleRegion.isEmpty()) {
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            secureFrameBuffer = true;
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
766970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    // invalidate the areas where a layer was removed
767970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
768970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian    mDirtyRegionRemovedLayer.clear();
769970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSecureFrameBuffer = secureFrameBuffer;
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::commitTransaction()
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDrawingState = mCurrentState;
778cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mResizeTransationPending = false;
779cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mTransactionCV.broadcast();
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handlePageFlip()
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool visibleRegions = mVisibleRegionsDirty;
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    visibleRegions |= lockPageFlip(currentLayers);
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw = graphicPlane(0).displayHardware();
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region screenRegion(hw.bounds());
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (visibleRegions) {
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region opaqueRegion;
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mWormholeRegion = screenRegion.subtract(opaqueRegion);
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = false;
795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unlockPageFlip(currentLayers);
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.andSelf(screenRegion);
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool recomputeVisibleRegions = false;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
805076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->lockPageFlip(recomputeVisibleRegions);
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return recomputeVisibleRegions;
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GraphicPlane& plane(graphicPlane(0));
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Transform& planeTransform(plane.transform());
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t count = currentLayers.size();
818076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
820076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->unlockPageFlip(planeTransform, mDirtyRegion);
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
825b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::handleRepaint()
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
828b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
829b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    mInvalidRegion.orSelf(mDirtyRegion);
830b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
831b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        // nothing to do
832b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        return;
833b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mDebugRegion)) {
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        debugFlashRegions();
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
839b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
840b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
841b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
842b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
845df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
846df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        (flags & DisplayHardware::BUFFER_PRESERVED))
847df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    {
84829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
84929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
85029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
85129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        if (flags & DisplayHardware::SWAP_RECTANGLE) {
85229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // FIXME: we really should be able to pass a region to
85329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // SWAP_RECTANGLE so that we don't have to redraw all this.
85429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            mDirtyRegion.set(mInvalidRegion.bounds());
85529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        } else {
85629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // in the BUFFER_PRESERVED case, obviously, we can update only
85729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // what's needed and nothing more.
85829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // NOTE: this is NOT a common case, as preserving the backbuffer
85929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // is costly and usually involves copying the whole update back.
86029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        }
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
86295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
86329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
864df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
86595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
86629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(mInvalidRegion.bounds());
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
86929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mInvalidRegion = mDirtyRegion;
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // compose all surfaces
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    composeSurfaces(mDirtyRegion);
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the dirty regions
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::composeSurfaces(const Region& dirty)
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // should never happen unless the window manager has a bug
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // draw something...
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        drawWormhole();
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const SurfaceFlinger& flinger(*this);
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
892076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
894076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Region& visibleRegion(layer->visibleRegionScreen);
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!visibleRegion.isEmpty())  {
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const Region clip(dirty.intersect(visibleRegion));
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!clip.isEmpty()) {
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                layer->draw(clip);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::unlockClients()
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = drawingLayers.size();
909076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBase> const* const layers = drawingLayers.array();
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; ++i) {
911076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = layers[i];
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->finishPageFlip();
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugFlashRegions()
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian     const DisplayHardware& hw(graphicPlane(0).displayHardware());
9190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian     const uint32_t flags = hw.getFlags();
920df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
921df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian     if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
922df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian             (flags & DisplayHardware::BUFFER_PRESERVED))) {
92395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian         const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
9240926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                 mDirtyRegion.bounds() : hw.bounds());
9250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian         composeSurfaces(repaint);
9260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian     }
9270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_TEXTURE_2D);
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_SCISSOR_TEST);
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
9340926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
9350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
9360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        glColor4x(0x10000, 0, 0x10000, 0x10000);
9370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
9380926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        glColor4x(0x10000, 0x10000, 0, 0x10000);
9390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
94220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
94320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
94420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.top },
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.left,  r.bottom },
948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.bottom },
949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { r.right, r.top }
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
9540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
955b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    if (mInvalidRegion.isEmpty()) {
956b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mDirtyRegion.dump("mDirtyRegion");
957b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        mInvalidRegion.dump("mInvalidRegion");
958b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    }
959b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    hw.flip(mInvalidRegion);
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project       usleep(mDebugRegion * 1000);
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnable(GL_SCISSOR_TEST);
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //mDirtyRegion.dump("mDirtyRegion");
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(graphicPlane(0).displayHardware());
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t width = hw.getWidth();
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int32_t height = hw.getHeight();
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(!mDebugBackground)) {
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glClearColorx(0,0,0,0);
98320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
98420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
98520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
98620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glClear(GL_COLOR_BUFFER_BIT);
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                { width, height }, { 0, height }  };
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_SHORT, 0, vertices);
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glEnable(GL_TEXTURE_2D);
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glMatrixMode(GL_TEXTURE);
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glLoadIdentity();
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
100420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator it = region.begin();
100520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        Region::const_iterator const end = region.end();
100620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        while (it != end) {
100720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian            const Rect& r = *it++;
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const GLint sy = height - (r.top + r.height());
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glScissor(r.left, sy, r.width(), r.height());
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::debugShowFPS() const
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mFrameCount;
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static int mLastFrameCount = 0;
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static nsecs_t mLastFpsTime = 0;
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static float mFps = 0;
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFrameCount++;
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t now = systemTime();
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    nsecs_t diff = now - mLastFpsTime;
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (diff > ms2ns(250)) {
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFpsTime = now;
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLastFrameCount = mFrameCount;
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // XXX: mFPS has the value we want
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1033076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1041076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
10443d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
10453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    if (err == NO_ERROR)
10463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        setTransactionFlags(eTransactionNeeded);
10473d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return err;
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1050076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->forceVisibilityTransaction();
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTraversalNeeded);
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1057076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10590852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian    if (layer == 0)
10600852e674127780a458c96b4df0c1e73af8731f32Mathias Agopian        return BAD_VALUE;
1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t i = mCurrentState.layersSortedByZ.add(
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                layer, &LayerBase::compareCurrentStateZ);
1063076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
1064076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (lbc != 0) {
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLayerMap.add(lbc->serverIndex(), lbc);
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1070076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1074076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
10759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian        sp<LayerBaseClient> layer =
10769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian            LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
1077076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mLayerMap.removeItem(layer->serverIndex());
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10859a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
10869a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
10878c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian    // remove the layer from the main list (through a transaction).
10889a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
10898c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
10903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
10913d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
10923d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // from the user because there is a race between BClient::destroySurface(),
10933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // ~BClient() and ~ISurface().
10949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
10959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
10969a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
10979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::free_resources_l()
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // free resources associated with disconnected clients
1101f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = disconnectedClients.size();
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0 ; i<count ; i++) {
1104f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        sp<Client> client = disconnectedClients[i];
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTokens.release(client->cid);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    disconnectedClients.clear();
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (delay > 0) {
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            signalDelayedEvent(delay);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            signalEvent();
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::openGlobalTransaction()
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_inc(&mTransactionCount);
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::closeGlobalTransaction()
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (android_atomic_dec(&mTransactionCount) == 1) {
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signalEvent();
1137cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1138cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // if there is a transaction with a resize, wait for it to
1139cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // take effect before returning.
1140cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        Mutex::Autolock _l(mStateLock);
1141cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        while (mResizeTransationPending) {
1142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            mTransactionCV.wait(mStateLock);
1143cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 1;
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
115762b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mCurrentState.freezeDisplay = 0;
1168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTransactionFlags(eTransactionNeeded);
1169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // flags is intended to communicate some sort of animation behavior
117162b74444be6742ab6b877918c85caeb9f2f1a2c9Mathias Agopian    // (for instance fading)
1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1175c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceFlinger::setOrientation(DisplayID dpy,
1176c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mCurrentState.orientation != orientation) {
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1184c08731e756868653d09d3e49b723706df3687070Mathias Agopian            mCurrentState.orientationType = flags;
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mCurrentState.orientation = orientation;
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            setTransactionFlags(eTransactionNeeded);
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mTransactionCV.wait(mStateLock);
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            orientation = BAD_VALUE;
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return orientation;
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ISurfaceFlingerClient::surface_data_t* params,
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1200076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<LayerBaseClient::Surface> surfaceHandle;
12026e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
12036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
12046e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
12056e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
12066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
12076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
12086e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1210f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    sp<Client> client = mClientsMap.valueFor(clientId);
1211f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    if (UNLIKELY(client == 0)) {
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createSurface() failed, client not found (id=%d)", clientId);
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return surfaceHandle;
1214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1217f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    int32_t id = client->generateId(pid);
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(id) >= NUM_LAYERS_MAX) {
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createSurface() failed, generateId = %d", id);
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return surfaceHandle;
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (UNLIKELY(flags & ePushBuffers)) {
12261c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian                layer = createPushBuffersSurfaceLocked(client, d, id,
12271c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian                        w, h, flags);
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
12291c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian                layer = createNormalSurfaceLocked(client, d, id,
12301c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian                        w, h, flags, format);
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
1234f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian            layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
1237f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian            layer = createDimSurfaceLocked(client, d, id, w, h, flags);
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1241076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(eTransactionNeeded);
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
12441c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        if (surfaceHandle != 0) {
12451c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->token = surfaceHandle->getToken();
12461c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->identity = surfaceHandle->getIdentity();
12471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->width = w;
12481c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->height = h;
12491c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian            params->format = format;
12501c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1256076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
1257f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
12581c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        int32_t id, uint32_t w, uint32_t h, uint32_t flags,
12591c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGB_565;
1269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1272076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<Layer> layer = new Layer(this, display, client, id);
1273f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(err == NO_ERROR)) {
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->initStates(w, h, flags);
1276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        addLayer_l(layer);
1277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1279076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1284076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
1285f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
1286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1288076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
1289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1294076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
1295f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
1296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1298076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client, id);
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1304076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
1305f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1308076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->initStates(w, h, flags);
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    addLayer_l(layer);
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::removeSurface(SurfaceID index)
13159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
13169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
13179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
13189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
13190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     *
13200aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
13210aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
13220aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
13249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
132548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
13260aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
13270aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    sp<LayerBaseClient> layer = getLayerUser_l(index);
132848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
132948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
133048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
133148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            layer->onRemoved();
133248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
133348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
13349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
13359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
13369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
13389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1340759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
13419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1342f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    class MessageDestroySurface : public MessageBase {
13430aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        SurfaceFlinger* flinger;
1344f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        sp<LayerBaseClient> layer;
1345f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    public:
13460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        MessageDestroySurface(
13470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
13480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            : flinger(flinger), layer(layer) { }
1349f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        virtual bool handler() {
1350cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            sp<LayerBaseClient> l(layer);
1351cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            layer.clear(); // clear it outside of the lock;
1352f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
1353759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian            /*
1354759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * remove the layer from the current list -- chances are that it's
1355759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * not in the list anyway, because it should have been removed
1356759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * already upon request of the client (eg: window manager).
1357759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * However, a buggy client could have not done that.
1358759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * Since we know we don't have any more clients, we don't need
1359759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             * to use the purgatory.
1360759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian             */
1361cd8c5e29c245e55a5f648b7a10f8586baf64e622Mathias Agopian            status_t err = flinger->removeLayer_l(l);
13628c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
13638c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1364f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian            return true;
1365f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1366f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    };
13673d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian
1368f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
1369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::setClientState(
1373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ClientID cid,
1374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t count,
1375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t* states)
1376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mStateLock);
1378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    cid <<= 16;
1380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i=0 ; i<count ; i++) {
1381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const layer_state_t& s = states[i];
13823d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
1383076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (layer != 0) {
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t what = s.what;
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & ePositionChanged) {
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setPosition(s.x, s.y))
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eLayerChanged) {
1390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setLayer(s.z)) {
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    mCurrentState.layersSortedByZ.reorder(
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            layer, &Layer::compareCurrentStateZ);
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // we need traversal (state changed)
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // AND transaction (list changed)
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTransactionNeeded|eTraversalNeeded;
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eSizeChanged) {
1399cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (layer->setSize(s.w, s.h)) {
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1401cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    mResizeTransationPending = true;
1402cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                }
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eAlphaChanged) {
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eMatrixChanged) {
1409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setMatrix(s.matrix))
1410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eTransparentRegionChanged) {
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setTransparentRegionHint(s.transparentRegion))
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (what & eVisibilityChanged) {
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (layer->setFlags(s.flags, s.mask))
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    flags |= eTraversalNeeded;
1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (flags) {
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTransactionFlags(flags);
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1428076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1430076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
1431076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return layer;
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenReleased(int dpy)
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::screenAcquired(int dpy)
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this may be called by a signal handler, we can't do too much in here
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    signalEvent();
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t SIZE = 1024;
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
1453375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian    if (!mDump.checkCalling()) {
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
14609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // figure out if we're stuck somewhere
14629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t now = systemTime();
14639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
14649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const nsecs_t inTransaction(mDebugInTransaction);
14659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
14669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
14679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
14689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
14699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
14709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
14719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
14729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
14739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
14749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
14769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
14779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE,
14789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
14799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
14809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
14819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
14829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        size_t s = mClientsMap.size();
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char name[64];
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<s ; i++) {
1486f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian            sp<Client> client = mClientsMap.valueAt(i);
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            sprintf(name, "  Client (id=0x%08x)", client->cid);
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            client->dump(name);
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const size_t count = currentLayers.size();
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            /*** LayerBase ***/
1494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const Layer::State& s = layer->drawingState();
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            snprintf(buffer, SIZE,
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "+ %s %p\n"
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "      "
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
1500401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian                    "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
1502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    layer->getTypeID(), layer.get(),
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    s.z, layer->tx(), layer->ty(), s.w, s.h,
1504401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian                    layer->needsBlending(), layer->needsDithering(),
1505401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian                    layer->contentDirty,
1506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    s.alpha, s.flags,
1507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    s.transform[0], s.transform[1],
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    s.transform[2], s.transform[3]);
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            result.append(buffer);
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            buffer[0] = 0;
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            /*** LayerBaseClient ***/
1512076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            sp<LayerBaseClient> lbc =
1513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
1514076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (lbc != 0) {
1515f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian                sp<Client> client(lbc->client.promote());
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                snprintf(buffer, SIZE,
1517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "      "
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "id=0x%08x, client=0x%08x, identity=%u\n",
1519f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian                        lbc->clientIndex(), client.get() ? client->cid : 0,
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        lbc->getIdentity());
1521cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1522cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                result.append(buffer);
1523cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                buffer[0] = 0;
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            /*** Layer ***/
1526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
1527076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (l != 0) {
152886f7329080cbb6f70d56278b005c820f0360d84bMathias Agopian                SharedBufferStack::Statistics stats = l->lcblk->getStats();
1529cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                result.append( l->lcblk->dump("      ") );
1530cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                sp<const Buffer> buf0(l->getBuffer(0));
1531cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                sp<const Buffer> buf1(l->getBuffer(1));
15324790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                uint32_t w0=0, h0=0, s0=0;
15334790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                uint32_t w1=0, h1=0, s1=0;
15344790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                if (buf0 != 0) {
15354790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    w0 = buf0->getWidth();
15364790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    h0 = buf0->getHeight();
15374790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    s0 = buf0->getStride();
15384790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                }
15394790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                if (buf1 != 0) {
15404790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    w1 = buf1->getWidth();
15414790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    h1 = buf1->getHeight();
15424790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                    s1 = buf1->getStride();
15434790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                }
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                snprintf(buffer, SIZE,
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "      "
1546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
154786f7329080cbb6f70d56278b005c820f0360d84bMathias Agopian                        " freezeLock=%p, dq-q-time=%u us\n",
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        l->pixelFormat(),
15494790a3c1a2899d92868b3912453e020752faa88cMathias Agopian                        w0, h0, s0, w1, h1, s1,
155086f7329080cbb6f70d56278b005c820f0360d84bMathias Agopian                        l->getFreezeLock().get(), stats.totalTime);
1551cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                result.append(buffer);
1552cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                buffer[0] = 0;
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            s.transparentRegion.dump(result, "transparentRegion");
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mWormholeRegion.dump(result, "WormholeRegion");
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE,
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeDisplay?"yes":"no", mFreezeCount,
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mCurrentState.orientation, hw.canDraw());
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
15659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        snprintf(buffer, SIZE,
15669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last eglSwapBuffers() time: %f us\n"
15679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                "  last transaction time     : %f us\n",
15689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
15699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        result.append(buffer);
15709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inSwapBuffersDuration || !locked) {
15719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
15729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inSwapBuffersDuration/1000.0);
15739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
15759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (inTransactionDuration || !locked) {
15769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            snprintf(buffer, SIZE, "  transaction time: %f us\n",
15779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    inTransactionDuration/1000.0);
15789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
15799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1580759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian        snprintf(buffer, SIZE, "  client count: %d\n", mClientsMap.size());
15813d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian        result.append(buffer);
1582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const BufferAllocator& alloc(BufferAllocator::get());
1583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        alloc.dump(result);
15849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
15859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (locked) {
15869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            mStateLock.unlock();
15879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    write(fd, result.string(), result.size());
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case OPEN_GLOBAL_TRANSACTION:
1599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CLOSE_GLOBAL_TRANSACTION:
1600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case FREEZE_DISPLAY:
1602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case UNFREEZE_DISPLAY:
1603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1608a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
1609375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1610375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                LOGE("Permission Denial: "
1611375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1612375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1618b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1619375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1620375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1621375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1622375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1623375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            LOGE("Permission Denial: "
1624375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
162901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1631cbc93ca8005d0a885d54b9a13c18ea07220feedfMathias Agopian            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1003:  // SHOW_BACKGROUND
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugBackground = n ? 1 : 0;
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
1642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                signalEvent();
1646cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1647cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1648cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1649cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1650cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1007: // set mFreezeCount
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mFreezeCount = data.readInt32();
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
165601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugBackground);
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectClient::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const int pgsize = getpagesize();
1681cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
16827303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
16837303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    mCblkHeap = new MemoryHeapBase(cblksize, 0,
16847303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian            "SurfaceFlinger Client control-block");
16857303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
1686cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
16877303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    if (ctrlblk) { // construct the shared structure in-place.
1688cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        new(ctrlblk) SharedClient;
1689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectClient::~Client() {
1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ctrlblk) {
1694cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        ctrlblk->~SharedClient();  // destroy our shared-structure.
1695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint32_t Client::generateId(int pid)
1699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint32_t i = clz( ~mBitmap );
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (i >= NUM_LAYERS_MAX) {
1702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_MEMORY;
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mPid = pid;
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mInUse.add(uint8_t(i));
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mBitmap |= 1<<(31-i);
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return i;
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1709076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1710076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t idx = mInUse.indexOf(id);
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (idx < 0)
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NAME_NOT_FOUND;
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mLayers.insertAt(layer, idx);
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1717076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Client::free(int32_t id)
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t idx = mInUse.remove(uint8_t(id));
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (idx >= 0) {
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBitmap &= ~(1<<(31-id));
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mLayers.removeItemsAt(idx);
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Client::isValid(int32_t i) const {
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> lbc;
1733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t idx = mInUse.indexOf(uint8_t(i));
1734076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (idx >= 0) {
1735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        lbc = mLayers[idx].promote();
1736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
1737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return lbc;
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Client::dump(const char* what)
1742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if 0
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#pragma mark -
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17507303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias AgopianBClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mId(cid), mFlinger(flinger), mCblk(cblk)
1752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBClient::~BClient() {
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // destroy all resources attached to this client
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFlinger->destroyConnection(mId);
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17607303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> BClient::getControlBlock() const {
17617303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mCblk;
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<ISurface> BClient::createSurface(
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ISurfaceFlingerClient::surface_data_t* params, int pid,
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BClient::destroySurface(SurfaceID sid)
1773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sid |= (mId << 16); // add the client-part to id
17759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return mFlinger->removeSurface(sid);
1776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BClient::setState(int32_t count, const layer_state_t* states)
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlinger->setClientState(mId, count, states);
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::GraphicPlane()
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mHw(0)
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane::~GraphicPlane() {
1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete mHw;
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool GraphicPlane::initialized() const {
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mHw ? true : false;
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mHw = hw;
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid GraphicPlane::setTransform(const Transform& tr) {
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform = tr;
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mGlobalTransform = mOrientationTransform * mTransform;
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::orientationToTransfrom(
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int orientation, int w, int h, Transform* tr)
1809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    float a, b, c, d, x, y;
1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (orientation) {
1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientationDefault:
1813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        a=1; b=0; c=0; d=1; x=0; y=0;
1814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation90:
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        a=0; b=-1; c=1; d=0; x=w; y=0;
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation180:
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        a=-1; b=0; c=0; d=-1; x=w; y=h;
1820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case ISurfaceComposer::eOrientation270:
1822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        a=0; b=1; c=-1; d=0; x=0; y=h;
1823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    default:
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr->set(a, b, c, d);
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tr->set(x, y);
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t GraphicPlane::setOrientation(int orientation)
1833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const DisplayHardware& hw(displayHardware());
1835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const float w = hw.getWidth();
1836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const float h = hw.getHeight();
1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (orientation == ISurfaceComposer::eOrientationDefault) {
1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // make sure the default orientation is optimal
1840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mOrientationTransform.reset();
18410d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian        mOrientation = orientation;
1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mGlobalTransform = mTransform;
1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // If the rotation can be handled in hardware, this is where
1847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the magic should happen.
1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(orientation == 42)) {
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        float a, b, c, d, x, y;
1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const float r = (3.14159265f / 180.0f) * 42.0f;
1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const float si = sinf(r);
1852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const float co = cosf(r);
1853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        a=co; b=-si; c=si; d=co;
1854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        x = si*(h*0.5f) + (1-co)*(w*0.5f);
1855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        y =-si*(w*0.5f) + (1-co)*(h*0.5f);
1856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mOrientationTransform.set(a, b, c, d);
1857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mOrientationTransform.set(x, y);
1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
1859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GraphicPlane::orientationToTransfrom(orientation, w, h,
1860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                &mOrientationTransform);
1861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
18620d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    mOrientation = orientation;
1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mGlobalTransform = mOrientationTransform * mTransform;
1864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst DisplayHardware& GraphicPlane::displayHardware() const {
1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return *mHw;
1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Transform& GraphicPlane::transform() const {
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mGlobalTransform;
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1875076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLDisplay GraphicPlane::getEGLDisplay() const {
1876076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mHw->getEGLDisplay();
1877076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
1878076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1882