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