SurfaceFlinger.cpp revision 81bac09fa6b01dd1495644d9c825c3666762fced
1d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath/*
2d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * Copyright (C) 2007 The Android Open Source Project
3d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath *
4d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License");
5d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * you may not use this file except in compliance with the License.
6d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * You may obtain a copy of the License at
7d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath *
8d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath *      http://www.apache.org/licenses/LICENSE-2.0
9d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath *
10d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * Unless required by applicable law or agreed to in writing, software
11d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
12d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * See the License for the specific language governing permissions and
14d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * limitations under the License.
15d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath */
16d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
17d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <stdlib.h>
184d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <stdio.h>
194d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <stdint.h>
20e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath#include <unistd.h>
21d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <fcntl.h>
22d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <errno.h>
23d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <math.h>
24d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <limits.h>
254d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <sys/types.h>
26d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <sys/stat.h>
27d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <sys/ioctl.h>
284d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
294d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <cutils/log.h>
304d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <cutils/properties.h>
311b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
32e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath#include <binder/IPCThreadState.h>
33e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath#include <binder/IServiceManager.h>
34d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <binder/MemoryHeapBase.h>
35d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
36d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <utils/String8.h>
37d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <utils/String16.h>
384d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <utils/StopWatch.h>
394d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
404d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath#include <ui/GraphicBufferAllocator.h>
41d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <ui/PixelFormat.h>
424d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
43d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <pixelflinger/pixelflinger.h>
44d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include <GLES/gl.h>
45d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
461b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#include "clz.h"
47d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include "GLExtensions.h"
48e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath#include "Layer.h"
491b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#include "LayerBlur.h"
5058f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak#include "LayerBuffer.h"
51d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include "LayerDim.h"
52d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include "SurfaceFlinger.h"
53d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
54d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#include "DisplayHardware/DisplayHardware.h"
55d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
56d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath/* ideally AID_GRAPHICS would be in a semi-public header
57d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath * or there would be a way to map a user/group name to its id
58d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath */
591b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#ifndef AID_GRAPHICS
601b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#define AID_GRAPHICS 1003
61d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#endif
62d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
63d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#define DISPLAY_COUNT       1
644d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
65e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamathnamespace android {
66e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
671b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak// ---------------------------------------------------------------------------
681b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
691b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakvoid SurfaceFlinger::instantiate() {
701b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    defaultServiceManager()->addService(
711b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            String16("SurfaceFlinger"), new SurfaceFlinger());
721b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
734d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
74d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamathvoid SurfaceFlinger::shutdown() {
75d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // we should unregister here, but not really because
761b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    // when (if) the service manager goes away, all the services
771b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    // it has a reference to will leave too.
781b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
791b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
801b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak// ---------------------------------------------------------------------------
811b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
821b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw SzczepaniakSurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
831b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    : lookup(rhs.lookup), layers(rhs.layers)
841b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak{
851b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
861b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
871b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakssize_t SurfaceFlinger::LayerVector::indexOf(
881b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        const sp<LayerBase>& key, size_t guess) const
891b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak{
901b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    if (guess<size() && lookup.keyAt(guess) == key)
911b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        return guess;
921b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    const ssize_t i = lookup.indexOfKey(key);
931b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    if (i>=0) {
941b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        const size_t idx = lookup.valueAt(i);
951b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        LOGE_IF(layers[idx]!=key,
961b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            "LayerVector[%p]: layers[%d]=%p, key=%p",
971b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            this, int(idx), layers[idx].get(), key.get());
981b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        return idx;
991b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
1001b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    return i;
1011b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
1021b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
1031b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakssize_t SurfaceFlinger::LayerVector::add(
1041b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        const sp<LayerBase>& layer,
105d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        Vector< sp<LayerBase> >::compar_t cmp)
106d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath{
107d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    size_t count = layers.size();
108d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    ssize_t l = 0;
109d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    ssize_t h = count-1;
1100e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath    ssize_t mid;
1110e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath    sp<LayerBase> const* a = layers.array();
1120e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath    while (l <= h) {
113d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mid = l + (h - l)/2;
114d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        const int c = cmp(a+mid, &layer);
115e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        if (c == 0)     { l = mid; break; }
116d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        else if (c<0)   { l = mid+1; }
1170e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        else            { h = mid-1; }
118d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    }
119d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    size_t order = l;
120d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    while (order<count && !cmp(&layer, a+order)) {
121d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        order++;
122d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    }
123d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    count = lookup.size();
124d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    for (size_t i=0 ; i<count ; i++) {
125d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        if (lookup.valueAt(i) >= order) {
126d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            lookup.editValueAt(i)++;
127d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        }
128d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    }
129d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    layers.insertAt(layer, order);
130d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    lookup.add(layer, order);
131d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    return order;
132d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath}
133d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
134d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamathssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
135d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath{
136d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const ssize_t keyIndex = lookup.indexOfKey(layer);
137d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    if (keyIndex >= 0) {
138d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        const size_t index = lookup.valueAt(keyIndex);
139d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        LOGE_IF(layers[index]!=layer,
140d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath                "LayerVector[%p]: layers[%u]=%p, layer=%p",
141d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath                this, int(index), layers[index].get(), layer.get());
142d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        layers.removeItemsAt(index);
143d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        lookup.removeItemsAt(keyIndex);
144d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        const size_t count = lookup.size();
145d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        for (size_t i=0 ; i<count ; i++) {
146d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            if (lookup.valueAt(i) >= size_t(index)) {
147d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath                lookup.editValueAt(i)--;
148d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            }
149d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        }
150d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        return index;
151d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    }
152d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    return NAME_NOT_FOUND;
153d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath}
154d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
155d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamathssize_t SurfaceFlinger::LayerVector::reorder(
156d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        const sp<LayerBase>& layer,
157d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        Vector< sp<LayerBase> >::compar_t cmp)
158d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath{
159d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // XXX: it's a little lame. but oh well...
160d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    ssize_t err = remove(layer);
161d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    if (err >=0)
162d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        err = add(layer, cmp);
163d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    return err;
164d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath}
165d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
166d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath// ---------------------------------------------------------------------------
167d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#if 0
168d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#pragma mark -
169d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath#endif
170d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
171d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan KamathSurfaceFlinger::SurfaceFlinger()
172d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    :   BnSurfaceComposer(), Thread(false),
173d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mTransactionFlags(0),
174d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mTransactionCount(0),
175d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mResizeTransationPending(false),
176d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mLayersRemoved(false),
177d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mBootTime(systemTime()),
178d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mHardwareTest("android.permission.HARDWARE_TEST"),
179d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
180d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mDump("android.permission.DUMP"),
181d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mVisibleRegionsDirty(false),
182d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mDeferReleaseConsole(false),
183d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mFreezeDisplay(false),
1840e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mFreezeCount(0),
185c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath        mFreezeDisplayTime(0),
1860e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mDebugRegion(0),
187c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath        mDebugBackground(0),
1880e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mDebugInSwapBuffers(0),
1890e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mLastSwapBufferTime(0),
1900e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mDebugInTransaction(0),
1910e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mLastTransactionTime(0),
192c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath        mBootFinished(false),
1930e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mConsoleSignals(0),
1940e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        mSecureFrameBuffer(0)
1954d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
1964d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    init();
1974d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
1984d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
1994d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathvoid SurfaceFlinger::init()
2004d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2014d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    LOGI("SurfaceFlinger is starting");
2024d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2034d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    // debugging stuff...
2044d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    char value[PROPERTY_VALUE_MAX];
2054d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    property_get("debug.sf.showupdates", value, "0");
2064d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    mDebugRegion = atoi(value);
2074d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    property_get("debug.sf.showbackground", value, "0");
2084d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    mDebugBackground = atoi(value);
2094d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2104d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    LOGI_IF(mDebugRegion,       "showupdates enabled");
2114d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    LOGI_IF(mDebugBackground,   "showbackground enabled");
2124d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2134d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2144d03462b374dfc080f0c7c78d458c102a26be5c6Narayan KamathSurfaceFlinger::~SurfaceFlinger()
2154d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2164d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    glDeleteTextures(1, &mWormholeTexName);
2174d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2184d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2194d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathoverlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
2204d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2214d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    return graphicPlane(0).displayHardware().getOverlayEngine();
2224d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2234d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2244d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathsp<IMemoryHeap> SurfaceFlinger::getCblk() const
2254d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
226e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    return mServerHeap;
2274d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2284d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2294d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathsp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
2304d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2314d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    sp<ISurfaceComposerClient> bclient;
2324d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    sp<Client> client(new Client(this));
2334d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    status_t err = client->initCheck();
2344d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    if (err == NO_ERROR) {
2354d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath        bclient = client;
2364d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    }
2374d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    return bclient;
2384d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2394d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2404d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathsp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
2414d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2424d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    sp<ISurfaceComposerClient> bclient;
2434d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    sp<UserClient> client(new UserClient(this));
2444d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    status_t err = client->initCheck();
2454d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    if (err == NO_ERROR) {
2464d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath        bclient = client;
2474d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    }
2484d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    return bclient;
2494d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2504d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2514d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2524d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathconst GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
2534d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2544d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
2554d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    const GraphicPlane& plane(mGraphicPlanes[dpy]);
2564d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    return plane;
2574d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2584d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2594d03462b374dfc080f0c7c78d458c102a26be5c6Narayan KamathGraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
2604d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2614d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    return const_cast<GraphicPlane&>(
2624d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
2634d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2644d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2654d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathvoid SurfaceFlinger::bootFinished()
2664d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2674d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    const nsecs_t now = systemTime();
2684d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    const nsecs_t duration = now - mBootTime;
2694d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2704d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    mBootFinished = true;
2714d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    property_set("ctl.stop", "bootanim");
2724d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath}
2734d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
2744d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamathvoid SurfaceFlinger::onFirstRef()
2754d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath{
2764d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
2774d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
278d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // Wait for the main thread to be done with its initialization
279d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    mReadyToRunBarrier.wait();
280d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath}
281d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
282d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamathstatic inline uint16_t pack565(int r, int g, int b) {
283d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    return (r<<11)|(g<<5)|b;
284d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath}
285d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
286d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamathstatus_t SurfaceFlinger::readyToRun()
287d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath{
288d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    LOGI(   "SurfaceFlinger's main thread ready to run. "
289d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            "Initializing graphics H/W...");
290d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
291d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // we only support one display currently
292d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    int dpy = 0;
293d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
294d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    {
295d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        // initialize the main display
296d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        GraphicPlane& plane(graphicPlane(dpy));
297d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        DisplayHardware* const hw = new DisplayHardware(this, dpy);
298d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        plane.setDisplayHardware(hw);
299d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    }
300d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
301d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // create the shared control-block
302d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    mServerHeap = new MemoryHeapBase(4096,
303d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
304d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
305d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
306d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
307d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
308d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
309d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    new(mServerCblk) surface_flinger_cblk_t;
310d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
311d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // initialize primary screen
312d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // (other display should be initialized in the same manner, but
313d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // asynchronously, as they could come and go. None of this is supported
314d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // yet).
315d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const GraphicPlane& plane(graphicPlane(dpy));
316d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const DisplayHardware& hw = plane.displayHardware();
317d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const uint32_t w = hw.getWidth();
318d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const uint32_t h = hw.getHeight();
319d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    const uint32_t f = hw.getFormat();
320d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    hw.makeCurrent();
321d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath
322d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    // initialize the shared control block
323e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    mServerCblk->connected |= 1<<dpy;
3241b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    display_cblk_t* dcblk = mServerCblk->displays + dpy;
325e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    memset(dcblk, 0, sizeof(display_cblk_t));
3261b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    dcblk->w            = plane.getWidth();
327e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    dcblk->h            = plane.getHeight();
328e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    dcblk->format       = f;
3291b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
330e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    dcblk->xdpi         = hw.getDpiX();
3311b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    dcblk->ydpi         = hw.getDpiY();
3321b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    dcblk->fps          = hw.getRefreshRate();
3331b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    dcblk->density      = hw.getDensity();
3341b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3351b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    // Initialize OpenGL|ES
3361b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3371b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glPixelStorei(GL_PACK_ALIGNMENT, 4);
3381b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glEnableClientState(GL_VERTEX_ARRAY);
3391b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glEnable(GL_SCISSOR_TEST);
3401b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glShadeModel(GL_FLAT);
341e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    glDisable(GL_DITHER);
342e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    glDisable(GL_CULL_FACE);
3431b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
344e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
3451b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    const uint16_t g1 = pack565(0x17,0x2f,0x17);
346e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const uint16_t textureData[4] = { g0, g1, g1, g0 };
347e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    glGenTextures(1, &mWormholeTexName);
3481b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
3491b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3501b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3511b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3521b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3531b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
3541b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
355e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
3561b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glViewport(0, 0, w, h);
357e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    glMatrixMode(GL_PROJECTION);
358e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    glLoadIdentity();
3591b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    glOrthof(0, w, h, 0, 0, 1);
360e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
361de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak   LayerDim::initDimmer(this, w, h);
3621b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3631b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    mReadyToRunBarrier.open();
364de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak
365de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak    /*
366de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak     *  We're now ready to accept clients...
367de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak     */
3681b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
369de1b5ae7a7567f03cfeecf1a62ddf429cb840474Przemyslaw Szczepaniak    // start boot animation
3701b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    property_set("ctl.start", "bootanim");
371e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
372e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    return NO_ERROR;
373e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath}
3741b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3751b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak// ----------------------------------------------------------------------------
3761b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#if 0
3771b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#pragma mark -
3781b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak#pragma mark Events Handler
379e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath#endif
3801b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3811b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakvoid SurfaceFlinger::waitForEvent()
3821b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak{
3831b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    while (true) {
3841b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        nsecs_t timeout = -1;
3851b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
3861b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        if (UNLIKELY(isFrozen())) {
3871b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            // wait 5 seconds
3881b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            const nsecs_t now = systemTime();
3891b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            if (mFreezeDisplayTime == 0) {
3901b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                mFreezeDisplayTime = now;
3911b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            }
3921b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
3931b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            timeout = waitTime>0 ? waitTime : 0;
3941b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        }
3951b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3961b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
3971b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
3981b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        // see if we timed out
3991b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        if (isFrozen()) {
4001b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            const nsecs_t now = systemTime();
4011b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            nsecs_t frozenTime = (now - mFreezeDisplayTime);
402e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            if (frozenTime >= freezeDisplayTimeout) {
403e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath                // we timed out and are still frozen
404e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
4051b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                        mFreezeDisplay, mFreezeCount);
4061b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                mFreezeDisplayTime = 0;
4071b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                mFreezeCount = 0;
408e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath                mFreezeDisplay = false;
40939268ffcb74f4c177e5e7427b66480c77743f928Narayan Kamath            }
4101b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        }
4111b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
4121b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        if (msg != 0) {
413e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            switch (msg->what) {
414e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath                case MessageQueue::INVALIDATE:
4151b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                    // invalidate message, just return to the main loop
4161b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak                    return;
4171b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak            }
4181b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        }
4191b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
4201b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
4211b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
4221b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakvoid SurfaceFlinger::signalEvent() {
4231b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    mEventQueue.invalidate();
4241b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak}
4251b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
4261b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniakvoid SurfaceFlinger::signal() const {
427e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    // this is the IPC call
428e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const_cast<SurfaceFlinger*>(this)->signalEvent();
42940d51e70037c8d32f9bbafd54775e526d86caf23Przemyslaw Szczepaniak}
430ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
431ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniakstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
432ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        nsecs_t reltime, uint32_t flags)
433ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak{
434ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    return mEventQueue.postMessage(msg, reltime, flags);
435ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak}
436ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
437ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniakstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
438ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        nsecs_t reltime, uint32_t flags)
439ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak{
440ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    status_t res = mEventQueue.postMessage(msg, reltime, flags);
441ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    if (res == NO_ERROR) {
442ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        msg->wait();
443ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
444ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    return res;
445ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak}
446ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
447ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak// ----------------------------------------------------------------------------
448ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak#if 0
449ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak#pragma mark -
450ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak#pragma mark Main loop
451ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak#endif
452ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
453ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniakbool SurfaceFlinger::threadLoop()
454ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak{
455ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    waitForEvent();
456ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
457ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    // check for transactions
458ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    if (UNLIKELY(mConsoleSignals)) {
459ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        handleConsoleEvents();
4601b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
46140d51e70037c8d32f9bbafd54775e526d86caf23Przemyslaw Szczepaniak
4621b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    if (LIKELY(mTransactionCount == 0)) {
4631b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        // if we're in a global transaction, don't do anything.
4641b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
4651b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        uint32_t transactionFlags = getTransactionFlags(mask);
4661b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        if (LIKELY(transactionFlags)) {
46740d51e70037c8d32f9bbafd54775e526d86caf23Przemyslaw Szczepaniak            handleTransaction(transactionFlags);
4681b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        }
4691b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
47040d51e70037c8d32f9bbafd54775e526d86caf23Przemyslaw Szczepaniak
4711b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    // post surfaces (if needed)
4721b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    handlePageFlip();
47358f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak
47458f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak    const DisplayHardware& hw(graphicPlane(0).displayHardware());
47558f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak    if (LIKELY(hw.canDraw() && !isFrozen())) {
47658f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak        // repaint the framebuffer (if needed)
47758f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak        handleRepaint();
4781b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
4791b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        // inform the h/w that we're done compositing
4801b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        hw.compositionComplete();
48158f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak
4821b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        // release the clients before we flip ('cause flip might block)
48358f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak        unlockClients();
48458f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak
48558f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak        postFramebuffer();
4861b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    } else {
48739268ffcb74f4c177e5e7427b66480c77743f928Narayan Kamath        // pretend we did the post
488e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        unlockClients();
489e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        usleep(16667); // 60 fps period
490e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
491e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    return true;
492e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath}
493e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
494e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamathvoid SurfaceFlinger::postFramebuffer()
495e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath{
496e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    if (!mInvalidRegion.isEmpty()) {
497e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        const DisplayHardware& hw(graphicPlane(0).displayHardware());
498e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        const nsecs_t now = systemTime();
499e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mDebugInSwapBuffers = now;
500e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        hw.flip(mInvalidRegion);
501e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mLastSwapBufferTime = systemTime() - now;
502e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mDebugInSwapBuffers = 0;
503e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mInvalidRegion.clear();
504e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
505e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath}
506e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
507e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamathvoid SurfaceFlinger::handleConsoleEvents()
508e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath{
509e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    // something to do with the console
510e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const DisplayHardware& hw = graphicPlane(0).displayHardware();
511e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
512e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    int what = android_atomic_and(0, &mConsoleSignals);
513e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    if (what & eConsoleAcquired) {
514e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        hw.acquireScreen();
5151b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
5161b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak
5171b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    if (mDeferReleaseConsole && hw.canDraw()) {
5186dfa6e2a9be08a3a0f152a7b772efc8ce2469bcePrzemyslaw Szczepaniak        // We got the release signal before the acquire signal
5191b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        mDeferReleaseConsole = false;
5201b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        hw.releaseScreen();
521e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
522e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
523e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    if (what & eConsoleReleased) {
5241b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak        if (hw.canDraw()) {
525e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            hw.releaseScreen();
526e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        } else {
527e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            mDeferReleaseConsole = true;
528e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        }
5291b5637ee32c5d4e5d857fa86a1b1c1db23d027b7Przemyslaw Szczepaniak    }
530e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
531e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    mDirtyRegion.set(hw.bounds());
532e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath}
533e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
534e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamathvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
535e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath{
536e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    Vector< sp<LayerBase> > ditchedLayers;
537e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
538e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    { // scope for the lock
539e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        Mutex::Autolock _l(mStateLock);
540e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        const nsecs_t now = systemTime();
541e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mDebugInTransaction = now;
542e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        handleTransactionLocked(transactionFlags, ditchedLayers);
543e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mLastTransactionTime = systemTime() - now;
544e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        mDebugInTransaction = 0;
545e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
546e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
547e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    // do this without lock held
548e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const size_t count = ditchedLayers.size();
549e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    for (size_t i=0 ; i<count ; i++) {
550e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        if (ditchedLayers[i] != 0) {
551e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            //LOGD("ditching layer %p", ditchedLayers[i].get());
552e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            ditchedLayers[i]->ditch();
553e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        }
554e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
555e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath}
556e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
557e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamathvoid SurfaceFlinger::handleTransactionLocked(
558e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
559e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath{
560e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
561e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const size_t count = currentLayers.size();
562e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
563e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    /*
564e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath     * Traversal of the children
565e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath     * (perform the transaction for each of them if needed)
566e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath     */
567e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
568e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
569e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    if (layersNeedTransaction) {
570e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        for (size_t i=0 ; i<count ; i++) {
571e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            const sp<LayerBase>& layer = currentLayers[i];
572e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
573e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            if (!trFlags) continue;
574e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
575e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            const uint32_t flags = layer->doTransaction(0);
576e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath            if (flags & Layer::eVisibleRegion)
577e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath                mVisibleRegionsDirty = true;
578e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        }
579e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    }
580e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
581e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    /*
582e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath     * Perform our own transaction if needed
583e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath     */
584e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath
585e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath    if (transactionFlags & eTransactionNeeded) {
586e5b8c4dfc70288f661e0da4f082dd51cc1399f86Narayan Kamath        if (mCurrentState.orientation != mDrawingState.orientation) {
587d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath            // the orientation has changed, recompute all visible regions
588            // and invalidate everything.
589
590            const int dpy = 0;
591            const int orientation = mCurrentState.orientation;
592            const uint32_t type = mCurrentState.orientationType;
593            GraphicPlane& plane(graphicPlane(dpy));
594            plane.setOrientation(orientation);
595
596            // update the shared control block
597            const DisplayHardware& hw(plane.displayHardware());
598            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
599            dcblk->orientation = orientation;
600            dcblk->w = plane.getWidth();
601            dcblk->h = plane.getHeight();
602
603            mVisibleRegionsDirty = true;
604            mDirtyRegion.set(hw.bounds());
605        }
606
607        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
608            // freezing or unfreezing the display -> trigger animation if needed
609            mFreezeDisplay = mCurrentState.freezeDisplay;
610            if (mFreezeDisplay)
611                 mFreezeDisplayTime = 0;
612        }
613
614        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
615            // layers have been added
616            mVisibleRegionsDirty = true;
617        }
618
619        // some layers might have been removed, so
620        // we need to update the regions they're exposing.
621        if (mLayersRemoved) {
622            mLayersRemoved = false;
623            mVisibleRegionsDirty = true;
624            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
625            const size_t count = previousLayers.size();
626            for (size_t i=0 ; i<count ; i++) {
627                const sp<LayerBase>& layer(previousLayers[i]);
628                if (currentLayers.indexOf( layer ) < 0) {
629                    // this layer is not visible anymore
630                    ditchedLayers.add(layer);
631                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
632                }
633            }
634        }
635    }
636
637    commitTransaction();
638}
639
640sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
641{
642    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
643}
644
645void SurfaceFlinger::computeVisibleRegions(
646    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
647{
648    const GraphicPlane& plane(graphicPlane(0));
649    const Transform& planeTransform(plane.transform());
650    const DisplayHardware& hw(plane.displayHardware());
651    const Region screenRegion(hw.bounds());
652
653    Region aboveOpaqueLayers;
654    Region aboveCoveredLayers;
655    Region dirty;
656
657    bool secureFrameBuffer = false;
658
659    size_t i = currentLayers.size();
660    while (i--) {
661        const sp<LayerBase>& layer = currentLayers[i];
662        layer->validateVisibility(planeTransform);
663
664        // start with the whole surface at its current location
665        const Layer::State& s(layer->drawingState());
666
667        /*
668         * opaqueRegion: area of a surface that is fully opaque.
669         */
670        Region opaqueRegion;
671
672        /*
673         * visibleRegion: area of a surface that is visible on screen
674         * and not fully transparent. This is essentially the layer's
675         * footprint minus the opaque regions above it.
676         * Areas covered by a translucent surface are considered visible.
677         */
678        Region visibleRegion;
679
680        /*
681         * coveredRegion: area of a surface that is covered by all
682         * visible regions above it (which includes the translucent areas).
683         */
684        Region coveredRegion;
685
686
687        // handle hidden surfaces by setting the visible region to empty
688        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
689            const bool translucent = layer->needsBlending();
690            const Rect bounds(layer->visibleBounds());
691            visibleRegion.set(bounds);
692            visibleRegion.andSelf(screenRegion);
693            if (!visibleRegion.isEmpty()) {
694                // Remove the transparent area from the visible region
695                if (translucent) {
696                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
697                }
698
699                // compute the opaque region
700                const int32_t layerOrientation = layer->getOrientation();
701                if (s.alpha==255 && !translucent &&
702                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
703                    // the opaque region is the layer's footprint
704                    opaqueRegion = visibleRegion;
705                }
706            }
707        }
708
709        // Clip the covered region to the visible region
710        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
711
712        // Update aboveCoveredLayers for next (lower) layer
713        aboveCoveredLayers.orSelf(visibleRegion);
714
715        // subtract the opaque region covered by the layers above us
716        visibleRegion.subtractSelf(aboveOpaqueLayers);
717
718        // compute this layer's dirty region
719        if (layer->contentDirty) {
720            // we need to invalidate the whole region
721            dirty = visibleRegion;
722            // as well, as the old visible region
723            dirty.orSelf(layer->visibleRegionScreen);
724            layer->contentDirty = false;
725        } else {
726            /* compute the exposed region:
727             *   the exposed region consists of two components:
728             *   1) what's VISIBLE now and was COVERED before
729             *   2) what's EXPOSED now less what was EXPOSED before
730             *
731             * note that (1) is conservative, we start with the whole
732             * visible region but only keep what used to be covered by
733             * something -- which mean it may have been exposed.
734             *
735             * (2) handles areas that were not covered by anything but got
736             * exposed because of a resize.
737             */
738            const Region newExposed = visibleRegion - coveredRegion;
739            const Region oldVisibleRegion = layer->visibleRegionScreen;
740            const Region oldCoveredRegion = layer->coveredRegionScreen;
741            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
742            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
743        }
744        dirty.subtractSelf(aboveOpaqueLayers);
745
746        // accumulate to the screen dirty region
747        dirtyRegion.orSelf(dirty);
748
749        // Update aboveOpaqueLayers for next (lower) layer
750        aboveOpaqueLayers.orSelf(opaqueRegion);
751
752        // Store the visible region is screen space
753        layer->setVisibleRegion(visibleRegion);
754        layer->setCoveredRegion(coveredRegion);
755
756        // If a secure layer is partially visible, lock-down the screen!
757        if (layer->isSecure() && !visibleRegion.isEmpty()) {
758            secureFrameBuffer = true;
759        }
760    }
761
762    // invalidate the areas where a layer was removed
763    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
764    mDirtyRegionRemovedLayer.clear();
765
766    mSecureFrameBuffer = secureFrameBuffer;
767    opaqueRegion = aboveOpaqueLayers;
768}
769
770
771void SurfaceFlinger::commitTransaction()
772{
773    mDrawingState = mCurrentState;
774    mResizeTransationPending = false;
775    mTransactionCV.broadcast();
776}
777
778void SurfaceFlinger::handlePageFlip()
779{
780    bool visibleRegions = mVisibleRegionsDirty;
781    LayerVector& currentLayers = const_cast<LayerVector&>(
782            mDrawingState.layersSortedByZ);
783    visibleRegions |= lockPageFlip(currentLayers);
784
785        const DisplayHardware& hw = graphicPlane(0).displayHardware();
786        const Region screenRegion(hw.bounds());
787        if (visibleRegions) {
788            Region opaqueRegion;
789            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
790            mWormholeRegion = screenRegion.subtract(opaqueRegion);
791            mVisibleRegionsDirty = false;
792        }
793
794    unlockPageFlip(currentLayers);
795    mDirtyRegion.andSelf(screenRegion);
796}
797
798bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
799{
800    bool recomputeVisibleRegions = false;
801    size_t count = currentLayers.size();
802    sp<LayerBase> const* layers = currentLayers.array();
803    for (size_t i=0 ; i<count ; i++) {
804        const sp<LayerBase>& layer(layers[i]);
805        layer->lockPageFlip(recomputeVisibleRegions);
806    }
807    return recomputeVisibleRegions;
808}
809
810void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
811{
812    const GraphicPlane& plane(graphicPlane(0));
813    const Transform& planeTransform(plane.transform());
814    size_t count = currentLayers.size();
815    sp<LayerBase> const* layers = currentLayers.array();
816    for (size_t i=0 ; i<count ; i++) {
817        const sp<LayerBase>& layer(layers[i]);
818        layer->unlockPageFlip(planeTransform, mDirtyRegion);
819    }
820}
821
822
823void SurfaceFlinger::handleRepaint()
824{
825    // compute the invalid region
826    mInvalidRegion.orSelf(mDirtyRegion);
827    if (mInvalidRegion.isEmpty()) {
828        // nothing to do
829        return;
830    }
831
832    if (UNLIKELY(mDebugRegion)) {
833        debugFlashRegions();
834    }
835
836    // set the frame buffer
837    const DisplayHardware& hw(graphicPlane(0).displayHardware());
838    glMatrixMode(GL_MODELVIEW);
839    glLoadIdentity();
840
841    uint32_t flags = hw.getFlags();
842    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
843        (flags & DisplayHardware::BUFFER_PRESERVED))
844    {
845        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
846        // takes a rectangle, we must make sure to update that whole
847        // rectangle in that case
848        if (flags & DisplayHardware::SWAP_RECTANGLE) {
849            // TODO: we really should be able to pass a region to
850            // SWAP_RECTANGLE so that we don't have to redraw all this.
851            mDirtyRegion.set(mInvalidRegion.bounds());
852        } else {
853            // in the BUFFER_PRESERVED case, obviously, we can update only
854            // what's needed and nothing more.
855            // NOTE: this is NOT a common case, as preserving the backbuffer
856            // is costly and usually involves copying the whole update back.
857        }
858    } else {
859        if (flags & DisplayHardware::PARTIAL_UPDATES) {
860            // We need to redraw the rectangle that will be updated
861            // (pushed to the framebuffer).
862            // This is needed because PARTIAL_UPDATES only takes one
863            // rectangle instead of a region (see DisplayHardware::flip())
864            mDirtyRegion.set(mInvalidRegion.bounds());
865        } else {
866            // we need to redraw everything (the whole screen)
867            mDirtyRegion.set(hw.bounds());
868            mInvalidRegion = mDirtyRegion;
869        }
870    }
871
872    // compose all surfaces
873    composeSurfaces(mDirtyRegion);
874
875    // clear the dirty regions
876    mDirtyRegion.clear();
877}
878
879void SurfaceFlinger::composeSurfaces(const Region& dirty)
880{
881    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
882        // should never happen unless the window manager has a bug
883        // draw something...
884        drawWormhole();
885    }
886    const SurfaceFlinger& flinger(*this);
887    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
888    const size_t count = drawingLayers.size();
889    sp<LayerBase> const* const layers = drawingLayers.array();
890    for (size_t i=0 ; i<count ; ++i) {
891        const sp<LayerBase>& layer = layers[i];
892        const Region& visibleRegion(layer->visibleRegionScreen);
893        if (!visibleRegion.isEmpty())  {
894            const Region clip(dirty.intersect(visibleRegion));
895            if (!clip.isEmpty()) {
896                layer->draw(clip);
897            }
898        }
899    }
900}
901
902void SurfaceFlinger::unlockClients()
903{
904    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
905    const size_t count = drawingLayers.size();
906    sp<LayerBase> const* const layers = drawingLayers.array();
907    for (size_t i=0 ; i<count ; ++i) {
908        const sp<LayerBase>& layer = layers[i];
909        layer->finishPageFlip();
910    }
911}
912
913void SurfaceFlinger::debugFlashRegions()
914{
915    const DisplayHardware& hw(graphicPlane(0).displayHardware());
916    const uint32_t flags = hw.getFlags();
917
918    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
919            (flags & DisplayHardware::BUFFER_PRESERVED))) {
920        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
921                mDirtyRegion.bounds() : hw.bounds());
922        composeSurfaces(repaint);
923    }
924
925    TextureManager::deactivateTextures();
926
927    glDisable(GL_BLEND);
928    glDisable(GL_DITHER);
929    glDisable(GL_SCISSOR_TEST);
930
931    static int toggle = 0;
932    toggle = 1 - toggle;
933    if (toggle) {
934        glColor4f(1, 0, 1, 1);
935    } else {
936        glColor4f(1, 1, 0, 1);
937    }
938
939    Region::const_iterator it = mDirtyRegion.begin();
940    Region::const_iterator const end = mDirtyRegion.end();
941    while (it != end) {
942        const Rect& r = *it++;
943        GLfloat vertices[][2] = {
944                { r.left,  r.top },
945                { r.left,  r.bottom },
946                { r.right, r.bottom },
947                { r.right, r.top }
948        };
949        glVertexPointer(2, GL_FLOAT, 0, vertices);
950        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
951    }
952
953    if (mInvalidRegion.isEmpty()) {
954        mDirtyRegion.dump("mDirtyRegion");
955        mInvalidRegion.dump("mInvalidRegion");
956    }
957    hw.flip(mInvalidRegion);
958
959    if (mDebugRegion > 1)
960        usleep(mDebugRegion * 1000);
961
962    glEnable(GL_SCISSOR_TEST);
963    //mDirtyRegion.dump("mDirtyRegion");
964}
965
966void SurfaceFlinger::drawWormhole() const
967{
968    const Region region(mWormholeRegion.intersect(mDirtyRegion));
969    if (region.isEmpty())
970        return;
971
972    const DisplayHardware& hw(graphicPlane(0).displayHardware());
973    const int32_t width = hw.getWidth();
974    const int32_t height = hw.getHeight();
975
976    glDisable(GL_BLEND);
977    glDisable(GL_DITHER);
978
979    if (LIKELY(!mDebugBackground)) {
980        glClearColor(0,0,0,0);
981        Region::const_iterator it = region.begin();
982        Region::const_iterator const end = region.end();
983        while (it != end) {
984            const Rect& r = *it++;
985            const GLint sy = height - (r.top + r.height());
986            glScissor(r.left, sy, r.width(), r.height());
987            glClear(GL_COLOR_BUFFER_BIT);
988        }
989    } else {
990        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
991                { width, height }, { 0, height }  };
992        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
993        glVertexPointer(2, GL_SHORT, 0, vertices);
994        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
995        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
996#if defined(GL_OES_texture_external)
997        if (GLExtensions::getInstance().haveTextureExternal()) {
998            glDisable(GL_TEXTURE_EXTERNAL_OES);
999        }
1000#endif
1001        glEnable(GL_TEXTURE_2D);
1002        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1003        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1004        glMatrixMode(GL_TEXTURE);
1005        glLoadIdentity();
1006        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
1007        Region::const_iterator it = region.begin();
1008        Region::const_iterator const end = region.end();
1009        while (it != end) {
1010            const Rect& r = *it++;
1011            const GLint sy = height - (r.top + r.height());
1012            glScissor(r.left, sy, r.width(), r.height());
1013            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1014        }
1015        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1016    }
1017}
1018
1019void SurfaceFlinger::debugShowFPS() const
1020{
1021    static int mFrameCount;
1022    static int mLastFrameCount = 0;
1023    static nsecs_t mLastFpsTime = 0;
1024    static float mFps = 0;
1025    mFrameCount++;
1026    nsecs_t now = systemTime();
1027    nsecs_t diff = now - mLastFpsTime;
1028    if (diff > ms2ns(250)) {
1029        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1030        mLastFpsTime = now;
1031        mLastFrameCount = mFrameCount;
1032    }
1033    // XXX: mFPS has the value we want
1034 }
1035
1036status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1037{
1038    Mutex::Autolock _l(mStateLock);
1039    addLayer_l(layer);
1040    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1041    return NO_ERROR;
1042}
1043
1044status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1045{
1046    ssize_t i = mCurrentState.layersSortedByZ.add(
1047                layer, &LayerBase::compareCurrentStateZ);
1048    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
1049}
1050
1051ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
1052        const sp<LayerBaseClient>& lbc)
1053{
1054    Mutex::Autolock _l(mStateLock);
1055
1056    // attach this layer to the client
1057    ssize_t name = client->attachLayer(lbc);
1058
1059    // add this layer to the current state list
1060    addLayer_l(lbc);
1061
1062    return name;
1063}
1064
1065status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
1066{
1067    Mutex::Autolock _l(mStateLock);
1068    status_t err = purgatorizeLayer_l(layer);
1069    if (err == NO_ERROR)
1070        setTransactionFlags(eTransactionNeeded);
1071    return err;
1072}
1073
1074status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1075{
1076    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
1077    if (lbc != 0) {
1078        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
1079    }
1080    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1081    if (index >= 0) {
1082        mLayersRemoved = true;
1083        return NO_ERROR;
1084    }
1085    return status_t(index);
1086}
1087
1088status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
1089{
1090    // remove the layer from the main list (through a transaction).
1091    ssize_t err = removeLayer_l(layerBase);
1092
1093    layerBase->onRemoved();
1094
1095    // it's possible that we don't find a layer, because it might
1096    // have been destroyed already -- this is not technically an error
1097    // from the user because there is a race between Client::destroySurface(),
1098    // ~Client() and ~ISurface().
1099    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
1100}
1101
1102status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1103{
1104    layer->forceVisibilityTransaction();
1105    setTransactionFlags(eTraversalNeeded);
1106    return NO_ERROR;
1107}
1108
1109uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1110{
1111    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1112}
1113
1114uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1115{
1116    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1117    if ((old & flags)==0) { // wake the server up
1118        signalEvent();
1119    }
1120    return old;
1121}
1122
1123void SurfaceFlinger::openGlobalTransaction()
1124{
1125    android_atomic_inc(&mTransactionCount);
1126}
1127
1128void SurfaceFlinger::closeGlobalTransaction()
1129{
1130    if (android_atomic_dec(&mTransactionCount) == 1) {
1131        signalEvent();
1132
1133        // if there is a transaction with a resize, wait for it to
1134        // take effect before returning.
1135        Mutex::Autolock _l(mStateLock);
1136        while (mResizeTransationPending) {
1137            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1138            if (CC_UNLIKELY(err != NO_ERROR)) {
1139                // just in case something goes wrong in SF, return to the
1140                // called after a few seconds.
1141                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1142                mResizeTransationPending = false;
1143                break;
1144            }
1145        }
1146    }
1147}
1148
1149status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1150{
1151    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1152        return BAD_VALUE;
1153
1154    Mutex::Autolock _l(mStateLock);
1155    mCurrentState.freezeDisplay = 1;
1156    setTransactionFlags(eTransactionNeeded);
1157
1158    // flags is intended to communicate some sort of animation behavior
1159    // (for instance fading)
1160    return NO_ERROR;
1161}
1162
1163status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1164{
1165    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1166        return BAD_VALUE;
1167
1168    Mutex::Autolock _l(mStateLock);
1169    mCurrentState.freezeDisplay = 0;
1170    setTransactionFlags(eTransactionNeeded);
1171
1172    // flags is intended to communicate some sort of animation behavior
1173    // (for instance fading)
1174    return NO_ERROR;
1175}
1176
1177int SurfaceFlinger::setOrientation(DisplayID dpy,
1178        int orientation, uint32_t flags)
1179{
1180    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1181        return BAD_VALUE;
1182
1183    Mutex::Autolock _l(mStateLock);
1184    if (mCurrentState.orientation != orientation) {
1185        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1186            mCurrentState.orientationType = flags;
1187            mCurrentState.orientation = orientation;
1188            setTransactionFlags(eTransactionNeeded);
1189            mTransactionCV.wait(mStateLock);
1190        } else {
1191            orientation = BAD_VALUE;
1192        }
1193    }
1194    return orientation;
1195}
1196
1197sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
1198        const String8& name, ISurfaceComposerClient::surface_data_t* params,
1199        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1200        uint32_t flags)
1201{
1202    sp<LayerBaseClient> layer;
1203    sp<LayerBaseClient::Surface> surfaceHandle;
1204
1205    if (int32_t(w|h) < 0) {
1206        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
1207                int(w), int(h));
1208        return surfaceHandle;
1209    }
1210
1211    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1212    sp<Layer> normalLayer;
1213    switch (flags & eFXSurfaceMask) {
1214        case eFXSurfaceNormal:
1215            if (UNLIKELY(flags & ePushBuffers)) {
1216                layer = createPushBuffersSurface(client, d, w, h, flags);
1217            } else {
1218                normalLayer = createNormalSurface(client, d, w, h, flags, format);
1219                layer = normalLayer;
1220            }
1221            break;
1222        case eFXSurfaceBlur:
1223            layer = createBlurSurface(client, d, w, h, flags);
1224            break;
1225        case eFXSurfaceDim:
1226            layer = createDimSurface(client, d, w, h, flags);
1227            break;
1228    }
1229
1230    if (layer != 0) {
1231        layer->initStates(w, h, flags);
1232        layer->setName(name);
1233        ssize_t token = addClientLayer(client, layer);
1234
1235        surfaceHandle = layer->getSurface();
1236        if (surfaceHandle != 0) {
1237            params->token = token;
1238            params->identity = surfaceHandle->getIdentity();
1239            params->width = w;
1240            params->height = h;
1241            params->format = format;
1242            if (normalLayer != 0) {
1243                Mutex::Autolock _l(mStateLock);
1244                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
1245            }
1246        }
1247
1248        setTransactionFlags(eTransactionNeeded);
1249    }
1250
1251    return surfaceHandle;
1252}
1253
1254sp<Layer> SurfaceFlinger::createNormalSurface(
1255        const sp<Client>& client, DisplayID display,
1256        uint32_t w, uint32_t h, uint32_t flags,
1257        PixelFormat& format)
1258{
1259    // initialize the surfaces
1260    switch (format) { // TODO: take h/w into account
1261    case PIXEL_FORMAT_TRANSPARENT:
1262    case PIXEL_FORMAT_TRANSLUCENT:
1263        format = PIXEL_FORMAT_RGBA_8888;
1264        break;
1265    case PIXEL_FORMAT_OPAQUE:
1266#ifdef NO_RGBX_8888
1267        format = PIXEL_FORMAT_RGB_565;
1268#else
1269        format = PIXEL_FORMAT_RGBX_8888;
1270#endif
1271        break;
1272    }
1273
1274#ifdef NO_RGBX_8888
1275    if (format == PIXEL_FORMAT_RGBX_8888)
1276        format = PIXEL_FORMAT_RGBA_8888;
1277#endif
1278
1279    sp<Layer> layer = new Layer(this, display, client);
1280    status_t err = layer->setBuffers(w, h, format, flags);
1281    if (LIKELY(err != NO_ERROR)) {
1282        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1283        layer.clear();
1284    }
1285    return layer;
1286}
1287
1288sp<LayerBlur> SurfaceFlinger::createBlurSurface(
1289        const sp<Client>& client, DisplayID display,
1290        uint32_t w, uint32_t h, uint32_t flags)
1291{
1292    sp<LayerBlur> layer = new LayerBlur(this, display, client);
1293    layer->initStates(w, h, flags);
1294    return layer;
1295}
1296
1297sp<LayerDim> SurfaceFlinger::createDimSurface(
1298        const sp<Client>& client, DisplayID display,
1299        uint32_t w, uint32_t h, uint32_t flags)
1300{
1301    sp<LayerDim> layer = new LayerDim(this, display, client);
1302    layer->initStates(w, h, flags);
1303    return layer;
1304}
1305
1306sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
1307        const sp<Client>& client, DisplayID display,
1308        uint32_t w, uint32_t h, uint32_t flags)
1309{
1310    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
1311    layer->initStates(w, h, flags);
1312    return layer;
1313}
1314
1315status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
1316{
1317    /*
1318     * called by the window manager, when a surface should be marked for
1319     * destruction.
1320     *
1321     * The surface is removed from the current and drawing lists, but placed
1322     * in the purgatory queue, so it's not destroyed right-away (we need
1323     * to wait for all client's references to go away first).
1324     */
1325
1326    status_t err = NAME_NOT_FOUND;
1327    Mutex::Autolock _l(mStateLock);
1328    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1329    if (layer != 0) {
1330        err = purgatorizeLayer_l(layer);
1331        if (err == NO_ERROR) {
1332            setTransactionFlags(eTransactionNeeded);
1333        }
1334    }
1335    return err;
1336}
1337
1338status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1339{
1340    // called by ~ISurface() when all references are gone
1341
1342    class MessageDestroySurface : public MessageBase {
1343        SurfaceFlinger* flinger;
1344        sp<LayerBaseClient> layer;
1345    public:
1346        MessageDestroySurface(
1347                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
1348            : flinger(flinger), layer(layer) { }
1349        virtual bool handler() {
1350            sp<LayerBaseClient> l(layer);
1351            layer.clear(); // clear it outside of the lock;
1352            Mutex::Autolock _l(flinger->mStateLock);
1353            /*
1354             * remove the layer from the current list -- chances are that it's
1355             * not in the list anyway, because it should have been removed
1356             * already upon request of the client (eg: window manager).
1357             * However, a buggy client could have not done that.
1358             * Since we know we don't have any more clients, we don't need
1359             * to use the purgatory.
1360             */
1361            status_t err = flinger->removeLayer_l(l);
1362            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1363                    "error removing layer=%p (%s)", l.get(), strerror(-err));
1364            return true;
1365        }
1366    };
1367
1368    postMessageAsync( new MessageDestroySurface(this, layer) );
1369    return NO_ERROR;
1370}
1371
1372status_t SurfaceFlinger::setClientState(
1373        const sp<Client>& client,
1374        int32_t count,
1375        const layer_state_t* states)
1376{
1377    Mutex::Autolock _l(mStateLock);
1378    uint32_t flags = 0;
1379    for (int i=0 ; i<count ; i++) {
1380        const layer_state_t& s(states[i]);
1381        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1382        if (layer != 0) {
1383            const uint32_t what = s.what;
1384            if (what & ePositionChanged) {
1385                if (layer->setPosition(s.x, s.y))
1386                    flags |= eTraversalNeeded;
1387            }
1388            if (what & eLayerChanged) {
1389                if (layer->setLayer(s.z)) {
1390                    mCurrentState.layersSortedByZ.reorder(
1391                            layer, &Layer::compareCurrentStateZ);
1392                    // we need traversal (state changed)
1393                    // AND transaction (list changed)
1394                    flags |= eTransactionNeeded|eTraversalNeeded;
1395                }
1396            }
1397            if (what & eSizeChanged) {
1398                if (layer->setSize(s.w, s.h)) {
1399                    flags |= eTraversalNeeded;
1400                    mResizeTransationPending = true;
1401                }
1402            }
1403            if (what & eAlphaChanged) {
1404                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1405                    flags |= eTraversalNeeded;
1406            }
1407            if (what & eMatrixChanged) {
1408                if (layer->setMatrix(s.matrix))
1409                    flags |= eTraversalNeeded;
1410            }
1411            if (what & eTransparentRegionChanged) {
1412                if (layer->setTransparentRegionHint(s.transparentRegion))
1413                    flags |= eTraversalNeeded;
1414            }
1415            if (what & eVisibilityChanged) {
1416                if (layer->setFlags(s.flags, s.mask))
1417                    flags |= eTraversalNeeded;
1418            }
1419        }
1420    }
1421    if (flags) {
1422        setTransactionFlags(flags);
1423    }
1424    return NO_ERROR;
1425}
1426
1427void SurfaceFlinger::screenReleased(int dpy)
1428{
1429    // this may be called by a signal handler, we can't do too much in here
1430    android_atomic_or(eConsoleReleased, &mConsoleSignals);
1431    signalEvent();
1432}
1433
1434void SurfaceFlinger::screenAcquired(int dpy)
1435{
1436    // this may be called by a signal handler, we can't do too much in here
1437    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1438    signalEvent();
1439}
1440
1441status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1442{
1443    const size_t SIZE = 1024;
1444    char buffer[SIZE];
1445    String8 result;
1446    if (!mDump.checkCalling()) {
1447        snprintf(buffer, SIZE, "Permission Denial: "
1448                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1449                IPCThreadState::self()->getCallingPid(),
1450                IPCThreadState::self()->getCallingUid());
1451        result.append(buffer);
1452    } else {
1453
1454        // figure out if we're stuck somewhere
1455        const nsecs_t now = systemTime();
1456        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
1457        const nsecs_t inTransaction(mDebugInTransaction);
1458        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
1459        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1460
1461        // Try to get the main lock, but don't insist if we can't
1462        // (this would indicate SF is stuck, but we want to be able to
1463        // print something in dumpsys).
1464        int retry = 3;
1465        while (mStateLock.tryLock()<0 && --retry>=0) {
1466            usleep(1000000);
1467        }
1468        const bool locked(retry >= 0);
1469        if (!locked) {
1470            snprintf(buffer, SIZE,
1471                    "SurfaceFlinger appears to be unresponsive, "
1472                    "dumping anyways (no locks held)\n");
1473            result.append(buffer);
1474        }
1475
1476        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1477        const size_t count = currentLayers.size();
1478        for (size_t i=0 ; i<count ; i++) {
1479            const sp<LayerBase>& layer(currentLayers[i]);
1480            layer->dump(result, buffer, SIZE);
1481            const Layer::State& s(layer->drawingState());
1482            s.transparentRegion.dump(result, "transparentRegion");
1483            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1484            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1485        }
1486
1487        mWormholeRegion.dump(result, "WormholeRegion");
1488        const DisplayHardware& hw(graphicPlane(0).displayHardware());
1489        snprintf(buffer, SIZE,
1490                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1491                mFreezeDisplay?"yes":"no", mFreezeCount,
1492                mCurrentState.orientation, hw.canDraw());
1493        result.append(buffer);
1494        snprintf(buffer, SIZE,
1495                "  last eglSwapBuffers() time: %f us\n"
1496                "  last transaction time     : %f us\n",
1497                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
1498        result.append(buffer);
1499
1500        if (inSwapBuffersDuration || !locked) {
1501            snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
1502                    inSwapBuffersDuration/1000.0);
1503            result.append(buffer);
1504        }
1505
1506        if (inTransactionDuration || !locked) {
1507            snprintf(buffer, SIZE, "  transaction time: %f us\n",
1508                    inTransactionDuration/1000.0);
1509            result.append(buffer);
1510        }
1511
1512        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1513        alloc.dump(result);
1514
1515        if (locked) {
1516            mStateLock.unlock();
1517        }
1518    }
1519    write(fd, result.string(), result.size());
1520    return NO_ERROR;
1521}
1522
1523status_t SurfaceFlinger::onTransact(
1524    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1525{
1526    switch (code) {
1527        case CREATE_CONNECTION:
1528        case OPEN_GLOBAL_TRANSACTION:
1529        case CLOSE_GLOBAL_TRANSACTION:
1530        case SET_ORIENTATION:
1531        case FREEZE_DISPLAY:
1532        case UNFREEZE_DISPLAY:
1533        case BOOT_FINISHED:
1534        {
1535            // codes that require permission check
1536            IPCThreadState* ipc = IPCThreadState::self();
1537            const int pid = ipc->getCallingPid();
1538            const int uid = ipc->getCallingUid();
1539            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1540                LOGE("Permission Denial: "
1541                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1542                return PERMISSION_DENIED;
1543            }
1544        }
1545    }
1546    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1547    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1548        CHECK_INTERFACE(ISurfaceComposer, data, reply);
1549        if (UNLIKELY(!mHardwareTest.checkCalling())) {
1550            IPCThreadState* ipc = IPCThreadState::self();
1551            const int pid = ipc->getCallingPid();
1552            const int uid = ipc->getCallingUid();
1553            LOGE("Permission Denial: "
1554                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1555            return PERMISSION_DENIED;
1556        }
1557        int n;
1558        switch (code) {
1559            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1560                return NO_ERROR;
1561            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
1562                return NO_ERROR;
1563            case 1002:  // SHOW_UPDATES
1564                n = data.readInt32();
1565                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1566                return NO_ERROR;
1567            case 1003:  // SHOW_BACKGROUND
1568                n = data.readInt32();
1569                mDebugBackground = n ? 1 : 0;
1570                return NO_ERROR;
1571            case 1004:{ // repaint everything
1572                Mutex::Autolock _l(mStateLock);
1573                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1574                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1575                signalEvent();
1576                return NO_ERROR;
1577            }
1578            case 1005:{ // force transaction
1579                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1580                return NO_ERROR;
1581            }
1582            case 1007: // set mFreezeCount
1583                mFreezeCount = data.readInt32();
1584                mFreezeDisplayTime = 0;
1585                return NO_ERROR;
1586            case 1010:  // interrogate.
1587                reply->writeInt32(0);
1588                reply->writeInt32(0);
1589                reply->writeInt32(mDebugRegion);
1590                reply->writeInt32(mDebugBackground);
1591                return NO_ERROR;
1592            case 1013: {
1593                Mutex::Autolock _l(mStateLock);
1594                const DisplayHardware& hw(graphicPlane(0).displayHardware());
1595                reply->writeInt32(hw.getPageFlipCount());
1596            }
1597            return NO_ERROR;
1598        }
1599    }
1600    return err;
1601}
1602
1603// ---------------------------------------------------------------------------
1604
1605sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
1606{
1607    sp<Layer> result;
1608    Mutex::Autolock _l(mStateLock);
1609    result = mLayerMap.valueFor( sur->asBinder() ).promote();
1610    return result;
1611}
1612
1613// ---------------------------------------------------------------------------
1614
1615Client::Client(const sp<SurfaceFlinger>& flinger)
1616    : mFlinger(flinger), mNameGenerator(1)
1617{
1618}
1619
1620Client::~Client()
1621{
1622    const size_t count = mLayers.size();
1623    for (size_t i=0 ; i<count ; i++) {
1624        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
1625        if (layer != 0) {
1626            mFlinger->removeLayer(layer);
1627        }
1628    }
1629}
1630
1631status_t Client::initCheck() const {
1632    return NO_ERROR;
1633}
1634
1635ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
1636{
1637    int32_t name = android_atomic_inc(&mNameGenerator);
1638    mLayers.add(name, layer);
1639    return name;
1640}
1641
1642void Client::detachLayer(const LayerBaseClient* layer)
1643{
1644    // we do a linear search here, because this doesn't happen often
1645    const size_t count = mLayers.size();
1646    for (size_t i=0 ; i<count ; i++) {
1647        if (mLayers.valueAt(i) == layer) {
1648            mLayers.removeItemsAt(i, 1);
1649            break;
1650        }
1651    }
1652}
1653sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1654    sp<LayerBaseClient> lbc;
1655    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
1656    if (layer != 0) {
1657        lbc = layer.promote();
1658        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
1659    }
1660    return lbc;
1661}
1662
1663sp<IMemoryHeap> Client::getControlBlock() const {
1664    return 0;
1665}
1666ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
1667    return -1;
1668}
1669sp<ISurface> Client::createSurface(
1670        ISurfaceComposerClient::surface_data_t* params, int pid,
1671        const String8& name,
1672        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1673        uint32_t flags)
1674{
1675    return mFlinger->createSurface(this, pid, name, params,
1676            display, w, h, format, flags);
1677}
1678status_t Client::destroySurface(SurfaceID sid) {
1679    return mFlinger->removeSurface(this, sid);
1680}
1681status_t Client::setState(int32_t count, const layer_state_t* states) {
1682    return mFlinger->setClientState(this, count, states);
1683}
1684
1685// ---------------------------------------------------------------------------
1686
1687UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
1688    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
1689{
1690    const int pgsize = getpagesize();
1691    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1692
1693    mCblkHeap = new MemoryHeapBase(cblksize, 0,
1694            "SurfaceFlinger Client control-block");
1695
1696    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1697    if (ctrlblk) { // construct the shared structure in-place.
1698        new(ctrlblk) SharedClient;
1699    }
1700}
1701
1702UserClient::~UserClient()
1703{
1704    if (ctrlblk) {
1705        ctrlblk->~SharedClient();  // destroy our shared-structure.
1706    }
1707
1708    /*
1709     * When a UserClient dies, it's unclear what to do exactly.
1710     * We could go ahead and destroy all surfaces linked to that client
1711     * however, it wouldn't be fair to the main Client
1712     * (usually the the window-manager), which might want to re-target
1713     * the layer to another UserClient.
1714     * I think the best is to do nothing, or not much; in most cases the
1715     * WM itself will go ahead and clean things up when it detects a client of
1716     * his has died.
1717     * The remaining question is what to display? currently we keep
1718     * just keep the current buffer.
1719     */
1720}
1721
1722status_t UserClient::initCheck() const {
1723    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
1724}
1725
1726void UserClient::detachLayer(const Layer* layer)
1727{
1728    int32_t name = layer->getToken();
1729    if (name >= 0) {
1730        int32_t mask = 1LU<<name;
1731        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
1732            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
1733        }
1734    }
1735}
1736
1737sp<IMemoryHeap> UserClient::getControlBlock() const {
1738    return mCblkHeap;
1739}
1740
1741ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
1742{
1743    int32_t name = NAME_NOT_FOUND;
1744    sp<Layer> layer(mFlinger->getLayer(sur));
1745    if (layer == 0) return name;
1746
1747    // if this layer already has a token, just return it
1748    name = layer->getToken();
1749    if ((name >= 0) && (layer->getClient() == this))
1750        return name;
1751
1752    name = 0;
1753    do {
1754        int32_t mask = 1LU<<name;
1755        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
1756            // we found and locked that name
1757            status_t err = layer->setToken(
1758                    const_cast<UserClient*>(this), ctrlblk, name);
1759            if (err != NO_ERROR) {
1760                // free the name
1761                android_atomic_and(~mask, &mBitmap);
1762                name = err;
1763            }
1764            break;
1765        }
1766        if (++name > 31)
1767            name = NO_MEMORY;
1768    } while(name >= 0);
1769
1770    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
1771    //        sur->asBinder().get(), name, this, mBitmap);
1772    return name;
1773}
1774
1775sp<ISurface> UserClient::createSurface(
1776        ISurfaceComposerClient::surface_data_t* params, int pid,
1777        const String8& name,
1778        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1779        uint32_t flags) {
1780    return 0;
1781}
1782status_t UserClient::destroySurface(SurfaceID sid) {
1783    return INVALID_OPERATION;
1784}
1785status_t UserClient::setState(int32_t count, const layer_state_t* states) {
1786    return INVALID_OPERATION;
1787}
1788
1789// ---------------------------------------------------------------------------
1790
1791GraphicPlane::GraphicPlane()
1792    : mHw(0)
1793{
1794}
1795
1796GraphicPlane::~GraphicPlane() {
1797    delete mHw;
1798}
1799
1800bool GraphicPlane::initialized() const {
1801    return mHw ? true : false;
1802}
1803
1804int GraphicPlane::getWidth() const {
1805    return mWidth;
1806}
1807
1808int GraphicPlane::getHeight() const {
1809    return mHeight;
1810}
1811
1812void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
1813{
1814    mHw = hw;
1815
1816    // initialize the display orientation transform.
1817    // it's a constant that should come from the display driver.
1818    int displayOrientation = ISurfaceComposer::eOrientationDefault;
1819    char property[PROPERTY_VALUE_MAX];
1820    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
1821        //displayOrientation
1822        switch (atoi(property)) {
1823        case 90:
1824            displayOrientation = ISurfaceComposer::eOrientation90;
1825            break;
1826        case 270:
1827            displayOrientation = ISurfaceComposer::eOrientation270;
1828            break;
1829        }
1830    }
1831
1832    const float w = hw->getWidth();
1833    const float h = hw->getHeight();
1834    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
1835            &mDisplayTransform);
1836    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
1837        mDisplayWidth = h;
1838        mDisplayHeight = w;
1839    } else {
1840        mDisplayWidth = w;
1841        mDisplayHeight = h;
1842    }
1843
1844    setOrientation(ISurfaceComposer::eOrientationDefault);
1845}
1846
1847status_t GraphicPlane::orientationToTransfrom(
1848        int orientation, int w, int h, Transform* tr)
1849{
1850    uint32_t flags = 0;
1851    switch (orientation) {
1852    case ISurfaceComposer::eOrientationDefault:
1853        flags = Transform::ROT_0;
1854        break;
1855    case ISurfaceComposer::eOrientation90:
1856        flags = Transform::ROT_90;
1857        break;
1858    case ISurfaceComposer::eOrientation180:
1859        flags = Transform::ROT_180;
1860        break;
1861    case ISurfaceComposer::eOrientation270:
1862        flags = Transform::ROT_270;
1863        break;
1864    default:
1865        return BAD_VALUE;
1866    }
1867    tr->set(flags, w, h);
1868    return NO_ERROR;
1869}
1870
1871status_t GraphicPlane::setOrientation(int orientation)
1872{
1873    // If the rotation can be handled in hardware, this is where
1874    // the magic should happen.
1875
1876    const DisplayHardware& hw(displayHardware());
1877    const float w = mDisplayWidth;
1878    const float h = mDisplayHeight;
1879    mWidth = int(w);
1880    mHeight = int(h);
1881
1882    Transform orientationTransform;
1883    GraphicPlane::orientationToTransfrom(orientation, w, h,
1884            &orientationTransform);
1885    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
1886        mWidth = int(h);
1887        mHeight = int(w);
1888    }
1889
1890    mOrientation = orientation;
1891    mGlobalTransform = mDisplayTransform * orientationTransform;
1892    return NO_ERROR;
1893}
1894
1895const DisplayHardware& GraphicPlane::displayHardware() const {
1896    return *mHw;
1897}
1898
1899const Transform& GraphicPlane::transform() const {
1900    return mGlobalTransform;
1901}
1902
1903EGLDisplay GraphicPlane::getEGLDisplay() const {
1904    return mHw->getEGLDisplay();
1905}
1906
1907// ---------------------------------------------------------------------------
1908
1909}; // namespace android
1910