Layer.cpp revision 19733a32799f792125913e746e8644d16f8dc223
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/compiler.h> 2599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <cutils/native_handle.h> 26076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/properties.h> 2799b49840d309727678b77403d6cc9f920111623fMathias Agopian 2899b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/Errors.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 30a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian#include <utils/StopWatch.h> 3199b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/Trace.h> 32375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/GraphicBuffer.h> 3499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <ui/PixelFormat.h> 359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 367e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian#include <gui/Surface.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Colorizer.h" 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayDevice.h" 41f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "Layer.h" 42f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "SurfaceFlinger.h" 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceTextureLayer.h" 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/HWComposer.h" 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "RenderEngine/RenderEngine.h" 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#define DEBUG_RESIZE 0 50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 52b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 53118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian// --------------------------------------------------------------------------- 54a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint32_t Layer::sSequence = 1; 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const String8& name, uint32_t w, uint32_t h, uint32_t flags) 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : contentDirty(false), 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sequence(uint32_t(android_atomic_inc(&sSequence))), 6196f0819f81293076e652792794a961543e6750d7Mathias Agopian mFlinger(flinger), 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTextureName(-1U), 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPremultipliedAlpha(true), 6496f0819f81293076e652792794a961543e6750d7Mathias Agopian mName("unnamed"), 6596f0819f81293076e652792794a961543e6750d7Mathias Agopian mDebug(false), 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFormat(PIXEL_FORMAT_NONE), 6796f0819f81293076e652792794a961543e6750d7Mathias Agopian mOpaqueLayer(true), 6896f0819f81293076e652792794a961543e6750d7Mathias Agopian mTransactionFlags(0), 6996f0819f81293076e652792794a961543e6750d7Mathias Agopian mQueuedFrames(0), 704f113740180b6512b43723c4728f262882dc9b45Mathias Agopian mCurrentTransform(0), 71b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 7296f0819f81293076e652792794a961543e6750d7Mathias Agopian mCurrentOpacity(true), 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRefreshPending(false), 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameLatencyNeeded(false), 7596f0819f81293076e652792794a961543e6750d7Mathias Agopian mFiltering(false), 7696f0819f81293076e652792794a961543e6750d7Mathias Agopian mNeedsFiltering(false), 770ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), 7896f0819f81293076e652792794a961543e6750d7Mathias Agopian mSecure(false), 7996f0819f81293076e652792794a961543e6750d7Mathias Agopian mProtectedByApp(false), 8096f0819f81293076e652792794a961543e6750d7Mathias Agopian mHasSurface(false), 81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mClientRef(client) 82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian{ 8396f0819f81293076e652792794a961543e6750d7Mathias Agopian mCurrentCrop.makeInvalid(); 844f113740180b6512b43723c4728f262882dc9b45Mathias Agopian mFlinger->getRenderEngine().genTextures(1, &mTextureName); 85b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); 864f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 874f113740180b6512b43723c4728f262882dc9b45Mathias Agopian uint32_t layerFlags = 0; 884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian if (flags & ISurfaceComposerClient::eHidden) 894f113740180b6512b43723c4728f262882dc9b45Mathias Agopian layerFlags = layer_state_t::eLayerHidden; 904f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 914f113740180b6512b43723c4728f262882dc9b45Mathias Agopian if (flags & ISurfaceComposerClient::eNonPremultiplied) 924f113740180b6512b43723c4728f262882dc9b45Mathias Agopian mPremultipliedAlpha = false; 93b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 94b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mName = name; 959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.active.w = w; 979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.active.h = h; 989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.active.crop.makeInvalid(); 999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.z = 0; 1009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.alpha = 0xFF; 101d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian mCurrentState.layerStack = 0; 1029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.flags = layerFlags; 1039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mCurrentState.sequence = 0; 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set(0, 0); 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.requested = mCurrentState.active; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // drawing state & current state are identical 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nsecs_t displayPeriod = 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameTracker.setDisplayRefreshPeriod(displayPeriod); 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onFirstRef() { 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBufferQueue = new SurfaceTextureLayer(mFlinger); 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName); 1190d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 1202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mSurfaceFlingerConsumer->setFrameAvailableListener(this); 1212b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mSurfaceFlingerConsumer->setName(mName); 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 12459119e658a12279e8fff508f8773843de2d90917Mathias Agopian#warning "disabling triple buffering" 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#else 127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project updateTransformHint(hw); 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1342b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias AgopianLayer::~Layer() { 1350d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian sp<Client> c(mClientRef.promote()); 1362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian if (c != 0) { 1372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian c->detachLayer(this); 1382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian } 1392b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian mFlinger->deleteTextureAsync(mTextureName); 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrameTracker.logAndResetStats(mName); 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// callbacks 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HWComposer::HWCLayerInterface* layer) { 149a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian if (layer) { 150a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian layer->onDisplayed(); 151a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); 1521f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 153a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian} 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onFrameAvailable() { 156a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian android_atomic_inc(&mQueuedFrames); 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->signalLayerUpdate(); 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// called with SurfaceFlinger::mStateLock from the drawing thread after 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// the layer has been remove from the current state list (and just before 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// it's removed from the drawing state list) 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onRemoved() { 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurfaceFlingerConsumer->abandon(); 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 1687e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian// set-up 1699a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// --------------------------------------------------------------------------- 1707303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst String8& Layer::getName() const { 172b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis return mName; 17328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis} 174c08731e756868653d09d3e49b723706df3687070Mathias Agopian 175582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 176d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian PixelFormat format, uint32_t flags) 177bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian{ 178bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian uint32_t const maxSurfaceDims = min( 179bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 180bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian 181bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian // never allow a surface larger than what our underlying GL implementation 182bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian // can handle. 183bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 18459119e658a12279e8fff508f8773843de2d90917Mathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 1859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian return BAD_VALUE; 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFormat = format; 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 190118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 191118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 1924a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 1934a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian mCurrentOpacity = getOpacityForFormat(format); 194118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 195118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 196118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 197118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 198118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 199118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return NO_ERROR; 200118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 201076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 202076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<IBinder> Layer::getHandle() { 203076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mLock); 204ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 205b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian LOG_ALWAYS_FATAL_IF(mHasSurface, 206b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian "Layer::getHandle() has already been called"); 207b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 2089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis mHasSurface = true; 2099575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 210118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian /* 211118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * The layer handle is just a BBinder object passed to the client 212118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * (remote process) -- we don't keep any reference on our side such that 213118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * the dtor is called when the remote side let go of its reference. 214118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * 215118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for 216118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * this layer when the handle is destroyed. 217118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian */ 218118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 219118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian class Handle : public BBinder, public LayerCleaner { 220118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian wp<const Layer> mOwner; 221118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian public: 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) 2231f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { 2241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian }; 2261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 22796f0819f81293076e652792794a961543e6750d7Mathias Agopian return new Handle(mFlinger, this); 228d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian} 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IGraphicBufferProducer> Layer::getBufferQueue() const { 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mBufferQueue; 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2330ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian 2347e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian// --------------------------------------------------------------------------- 2350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian// h/w composer set-up 2360ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian// --------------------------------------------------------------------------- 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect Layer::getContentCrop() const { 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this is the crop rectangle that applies to the buffer 240b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // itself (as opposed to the window) 241f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian Rect crop; 24296f0819f81293076e652792794a961543e6750d7Mathias Agopian if (!mCurrentCrop.isEmpty()) { 2431c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian // if the buffer crop is defined, we use that 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project crop = mCurrentCrop; 245b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } else if (mActiveBuffer != NULL) { 246f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian // otherwise we use the whole buffer 24796f0819f81293076e652792794a961543e6750d7Mathias Agopian crop = mActiveBuffer->getBounds(); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 249118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian // if we don't have a buffer yet, we use an empty/invalid crop 250118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian crop.makeInvalid(); 251118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 252118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return crop; 25396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 254ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 255698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) { 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (CC_LIKELY(exclude.isEmpty())) { 257f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian return win; 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 259f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian if (exclude.isRect()) { 260f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian return win.reduce(exclude.getBounds()); 261f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian } 262f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian return Region(win).subtract(exclude).getBounds(); 263f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian} 264f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian 265f6679fc6f70939643901f29a9a69e40c603e6e5fMathias AgopianRect Layer::computeBounds() const { 266f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian const Layer::State& s(getDrawingState()); 267f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian Rect win(s.active.w, s.active.h); 268f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian if (!s.active.crop.isEmpty()) { 269f6679fc6f70939643901f29a9a69e40c603e6e5fMathias Agopian win.intersect(s.active.crop, &win); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the transparent region and snap to the bounds 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return reduce(win, s.activeTransparentRegion); 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the content crop is the area of the content that gets scaled to the 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // layer's size. 27821230c6410bdab13cd2bd274da54b1e4061b6035Jeff Brown FloatRect crop(getContentCrop()); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the active.crop is the area of the window that gets cropped, but not 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // scaled in any ways. 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s(getDrawingState()); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // apply the projection's clipping to the window crop in 285550a11455a5155b078085fd5f464d7f3e5dfb7fcAndy McFadden // layerstack space, and convert-back to layer space. 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if there are no window scaling involved, this operation will map to full 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pixels in the buffer. 288e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian // FIXME: the 3 lines below can produce slightly incorrect clipping when we have 289e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian // a viewport clipping and a window transform. we should use floating point to fix this. 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2912944a2b3601ae5847cf54b3130dcf653a7b24b8aAndy McFadden Rect activeCrop(s.active.w, s.active.h); 292e2c2f9213f936f98db604dc9c126ff22f725a824Mathias Agopian if (!s.active.crop.isEmpty()) { 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project activeCrop = s.active.crop; 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 295ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project activeCrop = s.transform.transform(activeCrop); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project activeCrop.intersect(hw->getViewport(), &activeCrop); 2981bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian activeCrop = s.transform.inverse().transform(activeCrop); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // paranoia: make sure the window-crop is constrained in the 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // window's bounds 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the transparent region and snap to the bounds 305a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian activeCrop = reduce(activeCrop, s.activeTransparentRegion); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!activeCrop.isEmpty()) { 3089c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // Transform the window crop to match the buffer coordinate system, 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // which means using the inverse of the current transform set on the 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // SurfaceFlingerConsumer. 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t invTransform = mCurrentTransform; 3120dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian int winWidth = s.active.w; 3130dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian int winHeight = s.active.h; 3140dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 31596f0819f81293076e652792794a961543e6750d7Mathias Agopian invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 31696f0819f81293076e652792794a961543e6750d7Mathias Agopian NATIVE_WINDOW_TRANSFORM_FLIP_H; 317076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian winWidth = s.active.h; 318076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian winHeight = s.active.w; 3199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Rect winCrop = activeCrop.transform( 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project invTransform, s.active.w, s.active.h); 322dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 323bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // below, crop is intersected with winCrop expressed in crop's coordinate space 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project float xScale = crop.getWidth() / float(winWidth); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project float yScale = crop.getHeight() / float(winHeight); 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian float insetL = winCrop.left * xScale; 32874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian float insetT = winCrop.top * yScale; 32974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian float insetR = (winWidth - winCrop.right ) * xScale; 330bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian float insetB = (winHeight - winCrop.bottom) * yScale; 331bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian 33274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian crop.left += insetL; 333abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian crop.top += insetT; 334abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian crop.right -= insetR; 3359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian crop.bottom -= insetB; 3369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian } 33759119e658a12279e8fff508f8773843de2d90917Mathias Agopian return crop; 338d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian} 339d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 340d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianvoid Layer::setGeometry( 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const sp<const DisplayDevice>& hw, 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HWComposer::HWCLayerInterface& layer) 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setDefaultState(); 345f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian 346f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian // enable this layer 347bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian layer.setSkip(false); 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isSecure() && !hw->isSecure()) { 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setSkip(true); 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian // this gives us only the "orientation" component of the transform 35428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis const State& s(getDrawingState()); 35596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (!isOpaque() || s.alpha != 0xFF) { 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setBlending(mPremultipliedAlpha ? 35796f0819f81293076e652792794a961543e6750d7Mathias Agopian HWC_BLENDING_PREMULT : 35896f0819f81293076e652792794a961543e6750d7Mathias Agopian HWC_BLENDING_COVERAGE); 359b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3610dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian // apply the layer's transform, followed by the display's global transform 3620dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian // here we're guaranteed that the layer's transform preserves rects 3630dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian Rect frame(s.transform.transform(computeBounds())); 3640dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian frame.intersect(hw->getViewport(), &frame); 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& tr(hw->getTransform()); 3667303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian layer.setFrame(tr.transform(frame)); 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setCrop(computeCrop(hw)); 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setPlaneAlpha(s.alpha); 3699575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 371d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * Transformations are applied in this order: 37299b49840d309727678b77403d6cc9f920111623fMathias Agopian * 1) buffer orientation/flip/mirror 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 2) state transformation (window manager) 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 3) layer orientation (screen orientation) 3751bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 377970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian 3780656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform transform(tr * s.transform * bufferOrientation); 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 381a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // this gives us only the "orientation" component of the transform 382abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian const uint32_t orientation = transform.getOrientation(); 3834da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian if (orientation & Transform::ROT_INVALID) { 3844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian // we can only handle simple transformation 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setSkip(true); 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setTransform(orientation); 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian} 39073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian 391a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 3929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian HWComposer::HWCLayerInterface& layer) { 3939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // we have to set the visible region on every frame because 3949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // we currently free it during onLayerDisplayed(), which is called 3959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // after HWComposer::commit() -- every frame. 3963330b203039dea366d4981db1408a460134b2d2cMathias Agopian // Apply this display's projection's viewport to the visible region 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // before giving it to the HWC HAL. 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& tr = hw->getTransform(); 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer.setVisibleRegionScreen(visible); 401ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 402ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 403ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // layer yet, or if we ran out of memory 404ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian layer.setBuffer(mActiveBuffer); 405ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian} 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HWComposer::HWCLayerInterface& layer) { 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int fenceFd = -1; 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: there is a possible optimization here: we only need to set the 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // acquire fence the first time a new buffer is acquired on EACH display. 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer.getCompositionType() == HWC_OVERLAY) { 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (fence->isValid()) { 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project fenceFd = fence->dup(); 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (fenceFd == -1) { 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ALOGW("failed to dup layer fence, skipping sync: %d", errno); 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 421 } 422 } 423 layer.setAcquireFenceFd(fenceFd); 424} 425 426// --------------------------------------------------------------------------- 427// drawing... 428// --------------------------------------------------------------------------- 429 430void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 431 onDraw(hw, clip); 432} 433 434void Layer::draw(const sp<const DisplayDevice>& hw) { 435 onDraw( hw, Region(hw->bounds()) ); 436} 437 438void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 439{ 440 ATRACE_CALL(); 441 442 if (CC_UNLIKELY(mActiveBuffer == 0)) { 443 // the texture has not been created yet, this Layer has 444 // in fact never been drawn into. This happens frequently with 445 // SurfaceView because the WindowManager can't know when the client 446 // has drawn the first time. 447 448 // If there is nothing under us, we paint the screen in black, otherwise 449 // we just skip this update. 450 451 // figure out if there is something below us 452 Region under; 453 const SurfaceFlinger::LayerVector& drawingLayers( 454 mFlinger->mDrawingState.layersSortedByZ); 455 const size_t count = drawingLayers.size(); 456 for (size_t i=0 ; i<count ; ++i) { 457 const sp<Layer>& layer(drawingLayers[i]); 458 if (layer.get() == static_cast<Layer const*>(this)) 459 break; 460 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 461 } 462 // if not everything below us is covered, we plug the holes! 463 Region holes(clip.subtract(under)); 464 if (!holes.isEmpty()) { 465 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 466 } 467 return; 468 } 469 470 // Bind the current buffer to the GL texture, and wait for it to be 471 // ready for us to draw into. 472 status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 473 if (err != NO_ERROR) { 474 ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 475 // Go ahead and draw the buffer anyway; no matter what we do the screen 476 // is probably going to have something visibly wrong. 477 } 478 479 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 480 481 RenderEngine& engine(mFlinger->getRenderEngine()); 482 483 if (!blackOutLayer) { 484 // TODO: we could be more subtle with isFixedSize() 485 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 486 487 // Query the texture matrix given our current filtering mode. 488 float textureMatrix[16]; 489 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 490 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 491 492 // Set things up for texturing. 493 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 494 mTexture.setFiltering(useFiltering); 495 mTexture.setMatrix(textureMatrix); 496 497 engine.setupLayerTexturing(mTexture); 498 } else { 499 engine.setupLayerBlackedOut(); 500 } 501 drawWithOpenGL(hw, clip); 502 engine.disableTexturing(); 503} 504 505 506void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, 507 float red, float green, float blue, float alpha) const 508{ 509 RenderEngine& engine(mFlinger->getRenderEngine()); 510 computeGeometry(hw, mMesh); 511 engine.setupFillWithColor(red, green, blue, alpha); 512 engine.drawMesh(mMesh); 513} 514 515void Layer::clearWithOpenGL( 516 const sp<const DisplayDevice>& hw, const Region& clip) const { 517 clearWithOpenGL(hw, clip, 0,0,0,0); 518} 519 520void Layer::drawWithOpenGL( 521 const sp<const DisplayDevice>& hw, const Region& clip) const { 522 const uint32_t fbHeight = hw->getHeight(); 523 const State& s(getDrawingState()); 524 525 computeGeometry(hw, mMesh); 526 527 /* 528 * NOTE: the way we compute the texture coordinates here produces 529 * different results than when we take the HWC path -- in the later case 530 * the "source crop" is rounded to texel boundaries. 531 * This can produce significantly different results when the texture 532 * is scaled by a large amount. 533 * 534 * The GL code below is more logical (imho), and the difference with 535 * HWC is due to a limitation of the HWC API to integers -- a question 536 * is suspend is wether we should ignore this problem or revert to 537 * GL composition when a buffer scaling is applied (maybe with some 538 * minimal value)? Or, we could make GL behave like HWC -- but this feel 539 * like more of a hack. 540 */ 541 const Rect win(computeBounds()); 542 543 float left = float(win.left) / float(s.active.w); 544 float top = float(win.top) / float(s.active.h); 545 float right = float(win.right) / float(s.active.w); 546 float bottom = float(win.bottom) / float(s.active.h); 547 548 // TODO: we probably want to generate the texture coords with the mesh 549 // here we assume that we only have 4 vertices 550 Mesh::VertexArray texCoords(mMesh.getTexCoordArray()); 551 texCoords[0].s = left; 552 texCoords[0].t = 1.0f - top; 553 texCoords[1].s = left; 554 texCoords[1].t = 1.0f - bottom; 555 texCoords[2].s = right; 556 texCoords[2].t = 1.0f - bottom; 557 texCoords[3].s = right; 558 texCoords[3].t = 1.0f - top; 559 560 RenderEngine& engine(mFlinger->getRenderEngine()); 561 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha); 562 engine.drawMesh(mMesh); 563 engine.disableBlending(); 564} 565 566void Layer::setFiltering(bool filtering) { 567 mFiltering = filtering; 568} 569 570bool Layer::getFiltering() const { 571 return mFiltering; 572} 573 574// As documented in libhardware header, formats in the range 575// 0x100 - 0x1FF are specific to the HAL implementation, and 576// are known to have no alpha channel 577// TODO: move definition for device-specific range into 578// hardware.h, instead of using hard-coded values here. 579#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 580 581bool Layer::getOpacityForFormat(uint32_t format) { 582 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 583 return true; 584 } 585 switch (format) { 586 case HAL_PIXEL_FORMAT_RGBA_8888: 587 case HAL_PIXEL_FORMAT_BGRA_8888: 588 case HAL_PIXEL_FORMAT_sRGB_A_8888: 589 return false; 590 } 591 // in all other case, we have no blending (also for unknown formats) 592 return true; 593} 594 595// ---------------------------------------------------------------------------- 596// local state 597// ---------------------------------------------------------------------------- 598 599void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const 600{ 601 const Layer::State& s(getDrawingState()); 602 const Transform tr(hw->getTransform() * s.transform); 603 const uint32_t hw_h = hw->getHeight(); 604 Rect win(s.active.w, s.active.h); 605 if (!s.active.crop.isEmpty()) { 606 win.intersect(s.active.crop, &win); 607 } 608 // subtract the transparent region and snap to the bounds 609 win = reduce(win, s.activeTransparentRegion); 610 611 Mesh::VertexArray position(mesh.getPositionArray()); 612 tr.transform(position[0], win.left, win.top); 613 tr.transform(position[1], win.left, win.bottom); 614 tr.transform(position[2], win.right, win.bottom); 615 tr.transform(position[3], win.right, win.top); 616 for (size_t i=0 ; i<4 ; i++) { 617 position[i].y = hw_h - position[i].y; 618 } 619} 620 621bool Layer::isOpaque() const 622{ 623 // if we don't have a buffer yet, we're translucent regardless of the 624 // layer's opaque flag. 625 if (mActiveBuffer == 0) { 626 return false; 627 } 628 629 // if the layer has the opaque flag, then we're always opaque, 630 // otherwise we use the current buffer's format. 631 return mOpaqueLayer || mCurrentOpacity; 632} 633 634bool Layer::isProtected() const 635{ 636 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 637 return (activeBuffer != 0) && 638 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 639} 640 641bool Layer::isFixedSize() const { 642 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 643} 644 645bool Layer::isCropped() const { 646 return !mCurrentCrop.isEmpty(); 647} 648 649bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 650 return mNeedsFiltering || hw->needsFiltering(); 651} 652 653void Layer::setVisibleRegion(const Region& visibleRegion) { 654 // always called from main thread 655 this->visibleRegion = visibleRegion; 656} 657 658void Layer::setCoveredRegion(const Region& coveredRegion) { 659 // always called from main thread 660 this->coveredRegion = coveredRegion; 661} 662 663void Layer::setVisibleNonTransparentRegion(const Region& 664 setVisibleNonTransparentRegion) { 665 // always called from main thread 666 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 667} 668 669// ---------------------------------------------------------------------------- 670// transaction 671// ---------------------------------------------------------------------------- 672 673uint32_t Layer::doTransaction(uint32_t flags) { 674 ATRACE_CALL(); 675 676 const Layer::State& s(getDrawingState()); 677 const Layer::State& c(getCurrentState()); 678 679 const bool sizeChanged = (c.requested.w != s.requested.w) || 680 (c.requested.h != s.requested.h); 681 682 if (sizeChanged) { 683 // the size changed, we need to ask our client to request a new buffer 684 ALOGD_IF(DEBUG_RESIZE, 685 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 686 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 687 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 688 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 689 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 690 this, getName().string(), mCurrentTransform, mCurrentScalingMode, 691 c.active.w, c.active.h, 692 c.active.crop.left, 693 c.active.crop.top, 694 c.active.crop.right, 695 c.active.crop.bottom, 696 c.active.crop.getWidth(), 697 c.active.crop.getHeight(), 698 c.requested.w, c.requested.h, 699 c.requested.crop.left, 700 c.requested.crop.top, 701 c.requested.crop.right, 702 c.requested.crop.bottom, 703 c.requested.crop.getWidth(), 704 c.requested.crop.getHeight(), 705 s.active.w, s.active.h, 706 s.active.crop.left, 707 s.active.crop.top, 708 s.active.crop.right, 709 s.active.crop.bottom, 710 s.active.crop.getWidth(), 711 s.active.crop.getHeight(), 712 s.requested.w, s.requested.h, 713 s.requested.crop.left, 714 s.requested.crop.top, 715 s.requested.crop.right, 716 s.requested.crop.bottom, 717 s.requested.crop.getWidth(), 718 s.requested.crop.getHeight()); 719 720 // record the new size, form this point on, when the client request 721 // a buffer, it'll get the new size. 722 mSurfaceFlingerConsumer->setDefaultBufferSize( 723 c.requested.w, c.requested.h); 724 } 725 726 if (!isFixedSize()) { 727 728 const bool resizePending = (c.requested.w != c.active.w) || 729 (c.requested.h != c.active.h); 730 731 if (resizePending) { 732 // don't let Layer::doTransaction update the drawing state 733 // if we have a pending resize, unless we are in fixed-size mode. 734 // the drawing state will be updated only once we receive a buffer 735 // with the correct size. 736 // 737 // in particular, we want to make sure the clip (which is part 738 // of the geometry state) is latched together with the size but is 739 // latched immediately when no resizing is involved. 740 741 flags |= eDontUpdateGeometryState; 742 } 743 } 744 745 // always set active to requested, unless we're asked not to 746 // this is used by Layer, which special cases resizes. 747 if (flags & eDontUpdateGeometryState) { 748 } else { 749 Layer::State& editCurrentState(getCurrentState()); 750 editCurrentState.active = c.requested; 751 } 752 753 if (s.active != c.active) { 754 // invalidate and recompute the visible regions if needed 755 flags |= Layer::eVisibleRegion; 756 } 757 758 if (c.sequence != s.sequence) { 759 // invalidate and recompute the visible regions if needed 760 flags |= eVisibleRegion; 761 this->contentDirty = true; 762 763 // we may use linear filtering, if the matrix scales us 764 const uint8_t type = c.transform.getType(); 765 mNeedsFiltering = (!c.transform.preserveRects() || 766 (type >= Transform::SCALE)); 767 } 768 769 // Commit the transaction 770 commitTransaction(); 771 return flags; 772} 773 774void Layer::commitTransaction() { 775 mDrawingState = mCurrentState; 776} 777 778uint32_t Layer::getTransactionFlags(uint32_t flags) { 779 return android_atomic_and(~flags, &mTransactionFlags) & flags; 780} 781 782uint32_t Layer::setTransactionFlags(uint32_t flags) { 783 return android_atomic_or(flags, &mTransactionFlags); 784} 785 786bool Layer::setPosition(float x, float y) { 787 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 788 return false; 789 mCurrentState.sequence++; 790 mCurrentState.transform.set(x, y); 791 setTransactionFlags(eTransactionNeeded); 792 return true; 793} 794bool Layer::setLayer(uint32_t z) { 795 if (mCurrentState.z == z) 796 return false; 797 mCurrentState.sequence++; 798 mCurrentState.z = z; 799 setTransactionFlags(eTransactionNeeded); 800 return true; 801} 802bool Layer::setSize(uint32_t w, uint32_t h) { 803 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 804 return false; 805 mCurrentState.requested.w = w; 806 mCurrentState.requested.h = h; 807 setTransactionFlags(eTransactionNeeded); 808 return true; 809} 810bool Layer::setAlpha(uint8_t alpha) { 811 if (mCurrentState.alpha == alpha) 812 return false; 813 mCurrentState.sequence++; 814 mCurrentState.alpha = alpha; 815 setTransactionFlags(eTransactionNeeded); 816 return true; 817} 818bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 819 mCurrentState.sequence++; 820 mCurrentState.transform.set( 821 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 822 setTransactionFlags(eTransactionNeeded); 823 return true; 824} 825bool Layer::setTransparentRegionHint(const Region& transparent) { 826 mCurrentState.requestedTransparentRegion = transparent; 827 setTransactionFlags(eTransactionNeeded); 828 return true; 829} 830bool Layer::setFlags(uint8_t flags, uint8_t mask) { 831 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 832 if (mCurrentState.flags == newFlags) 833 return false; 834 mCurrentState.sequence++; 835 mCurrentState.flags = newFlags; 836 setTransactionFlags(eTransactionNeeded); 837 return true; 838} 839bool Layer::setCrop(const Rect& crop) { 840 if (mCurrentState.requested.crop == crop) 841 return false; 842 mCurrentState.sequence++; 843 mCurrentState.requested.crop = crop; 844 setTransactionFlags(eTransactionNeeded); 845 return true; 846} 847 848bool Layer::setLayerStack(uint32_t layerStack) { 849 if (mCurrentState.layerStack == layerStack) 850 return false; 851 mCurrentState.sequence++; 852 mCurrentState.layerStack = layerStack; 853 setTransactionFlags(eTransactionNeeded); 854 return true; 855} 856 857// ---------------------------------------------------------------------------- 858// pageflip handling... 859// ---------------------------------------------------------------------------- 860 861bool Layer::onPreComposition() { 862 mRefreshPending = false; 863 return mQueuedFrames > 0; 864} 865 866void Layer::onPostComposition() { 867 if (mFrameLatencyNeeded) { 868 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 869 mFrameTracker.setDesiredPresentTime(desiredPresentTime); 870 871 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 872 if (frameReadyFence->isValid()) { 873 mFrameTracker.setFrameReadyFence(frameReadyFence); 874 } else { 875 // There was no fence for this frame, so assume that it was ready 876 // to be presented at the desired present time. 877 mFrameTracker.setFrameReadyTime(desiredPresentTime); 878 } 879 880 const HWComposer& hwc = mFlinger->getHwComposer(); 881 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 882 if (presentFence->isValid()) { 883 mFrameTracker.setActualPresentFence(presentFence); 884 } else { 885 // The HWC doesn't support present fences, so use the refresh 886 // timestamp instead. 887 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 888 mFrameTracker.setActualPresentTime(presentTime); 889 } 890 891 mFrameTracker.advanceFrame(); 892 mFrameLatencyNeeded = false; 893 } 894} 895 896bool Layer::isVisible() const { 897 const Layer::State& s(mDrawingState); 898 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 899 && (mActiveBuffer != NULL); 900} 901 902Region Layer::latchBuffer(bool& recomputeVisibleRegions) 903{ 904 ATRACE_CALL(); 905 906 Region outDirtyRegion; 907 if (mQueuedFrames > 0) { 908 909 // if we've already called updateTexImage() without going through 910 // a composition step, we have to skip this layer at this point 911 // because we cannot call updateTeximage() without a corresponding 912 // compositionComplete() call. 913 // we'll trigger an update in onPreComposition(). 914 if (mRefreshPending) { 915 return outDirtyRegion; 916 } 917 918 // Capture the old state of the layer for comparisons later 919 const bool oldOpacity = isOpaque(); 920 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 921 922 struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 923 Layer::State& front; 924 Layer::State& current; 925 bool& recomputeVisibleRegions; 926 Reject(Layer::State& front, Layer::State& current, 927 bool& recomputeVisibleRegions) 928 : front(front), current(current), 929 recomputeVisibleRegions(recomputeVisibleRegions) { 930 } 931 932 virtual bool reject(const sp<GraphicBuffer>& buf, 933 const IGraphicBufferConsumer::BufferItem& item) { 934 if (buf == NULL) { 935 return false; 936 } 937 938 uint32_t bufWidth = buf->getWidth(); 939 uint32_t bufHeight = buf->getHeight(); 940 941 // check that we received a buffer of the right size 942 // (Take the buffer's orientation into account) 943 if (item.mTransform & Transform::ROT_90) { 944 swap(bufWidth, bufHeight); 945 } 946 947 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 948 if (front.active != front.requested) { 949 950 if (isFixedSize || 951 (bufWidth == front.requested.w && 952 bufHeight == front.requested.h)) 953 { 954 // Here we pretend the transaction happened by updating the 955 // current and drawing states. Drawing state is only accessed 956 // in this thread, no need to have it locked 957 front.active = front.requested; 958 959 // We also need to update the current state so that 960 // we don't end-up overwriting the drawing state with 961 // this stale current state during the next transaction 962 // 963 // NOTE: We don't need to hold the transaction lock here 964 // because State::active is only accessed from this thread. 965 current.active = front.active; 966 967 // recompute visible region 968 recomputeVisibleRegions = true; 969 } 970 971 ALOGD_IF(DEBUG_RESIZE, 972 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 973 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 974 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 975 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 976 front.active.w, front.active.h, 977 front.active.crop.left, 978 front.active.crop.top, 979 front.active.crop.right, 980 front.active.crop.bottom, 981 front.active.crop.getWidth(), 982 front.active.crop.getHeight(), 983 front.requested.w, front.requested.h, 984 front.requested.crop.left, 985 front.requested.crop.top, 986 front.requested.crop.right, 987 front.requested.crop.bottom, 988 front.requested.crop.getWidth(), 989 front.requested.crop.getHeight()); 990 } 991 992 if (!isFixedSize) { 993 if (front.active.w != bufWidth || 994 front.active.h != bufHeight) { 995 // reject this buffer 996 //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}", 997 // bufWidth, bufHeight, front.active.w, front.active.h); 998 return true; 999 } 1000 } 1001 1002 // if the transparent region has changed (this test is 1003 // conservative, but that's fine, worst case we're doing 1004 // a bit of extra work), we latch the new one and we 1005 // trigger a visible-region recompute. 1006 if (!front.activeTransparentRegion.isTriviallyEqual( 1007 front.requestedTransparentRegion)) { 1008 front.activeTransparentRegion = front.requestedTransparentRegion; 1009 1010 // We also need to update the current state so that 1011 // we don't end-up overwriting the drawing state with 1012 // this stale current state during the next transaction 1013 // 1014 // NOTE: We don't need to hold the transaction lock here 1015 // because State::active is only accessed from this thread. 1016 current.activeTransparentRegion = front.activeTransparentRegion; 1017 1018 // recompute visible region 1019 recomputeVisibleRegions = true; 1020 } 1021 1022 return false; 1023 } 1024 }; 1025 1026 1027 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions); 1028 1029 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r); 1030 if (updateResult == BufferQueue::PRESENT_LATER) { 1031 // Producer doesn't want buffer to be displayed yet. Signal a 1032 // layer update so we check again at the next opportunity. 1033 mFlinger->signalLayerUpdate(); 1034 return outDirtyRegion; 1035 } 1036 1037 // Decrement the queued-frames count. Signal another event if we 1038 // have more frames pending. 1039 if (android_atomic_dec(&mQueuedFrames) > 1) { 1040 mFlinger->signalLayerUpdate(); 1041 } 1042 1043 if (updateResult != NO_ERROR) { 1044 // something happened! 1045 recomputeVisibleRegions = true; 1046 return outDirtyRegion; 1047 } 1048 1049 // update the active buffer 1050 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1051 if (mActiveBuffer == NULL) { 1052 // this can only happen if the very first buffer was rejected. 1053 return outDirtyRegion; 1054 } 1055 1056 mRefreshPending = true; 1057 mFrameLatencyNeeded = true; 1058 if (oldActiveBuffer == NULL) { 1059 // the first time we receive a buffer, we need to trigger a 1060 // geometry invalidation. 1061 recomputeVisibleRegions = true; 1062 } 1063 1064 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1065 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1066 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1067 if ((crop != mCurrentCrop) || 1068 (transform != mCurrentTransform) || 1069 (scalingMode != mCurrentScalingMode)) 1070 { 1071 mCurrentCrop = crop; 1072 mCurrentTransform = transform; 1073 mCurrentScalingMode = scalingMode; 1074 recomputeVisibleRegions = true; 1075 } 1076 1077 if (oldActiveBuffer != NULL) { 1078 uint32_t bufWidth = mActiveBuffer->getWidth(); 1079 uint32_t bufHeight = mActiveBuffer->getHeight(); 1080 if (bufWidth != uint32_t(oldActiveBuffer->width) || 1081 bufHeight != uint32_t(oldActiveBuffer->height)) { 1082 recomputeVisibleRegions = true; 1083 } 1084 } 1085 1086 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 1087 if (oldOpacity != isOpaque()) { 1088 recomputeVisibleRegions = true; 1089 } 1090 1091 // FIXME: postedRegion should be dirty & bounds 1092 const Layer::State& s(getDrawingState()); 1093 Region dirtyRegion(Rect(s.active.w, s.active.h)); 1094 1095 // transform the dirty region to window-manager space 1096 outDirtyRegion = (s.transform.transform(dirtyRegion)); 1097 } 1098 return outDirtyRegion; 1099} 1100 1101uint32_t Layer::getEffectiveUsage(uint32_t usage) const 1102{ 1103 // TODO: should we do something special if mSecure is set? 1104 if (mProtectedByApp) { 1105 // need a hardware-protected path to external video sink 1106 usage |= GraphicBuffer::USAGE_PROTECTED; 1107 } 1108 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 1109 return usage; 1110} 1111 1112void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 1113 uint32_t orientation = 0; 1114 if (!mFlinger->mDebugDisableTransformHint) { 1115 // The transform hint is used to improve performance, but we can 1116 // only have a single transform hint, it cannot 1117 // apply to all displays. 1118 const Transform& planeTransform(hw->getTransform()); 1119 orientation = planeTransform.getOrientation(); 1120 if (orientation & Transform::ROT_INVALID) { 1121 orientation = 0; 1122 } 1123 } 1124 mSurfaceFlingerConsumer->setTransformHint(orientation); 1125} 1126 1127// ---------------------------------------------------------------------------- 1128// debugging 1129// ---------------------------------------------------------------------------- 1130 1131void Layer::dump(String8& result, Colorizer& colorizer) const 1132{ 1133 const Layer::State& s(getDrawingState()); 1134 1135 colorizer.colorize(result, Colorizer::GREEN); 1136 result.appendFormat( 1137 "+ %s %p (%s)\n", 1138 getTypeId(), this, getName().string()); 1139 colorizer.reset(result); 1140 1141 s.activeTransparentRegion.dump(result, "transparentRegion"); 1142 visibleRegion.dump(result, "visibleRegion"); 1143 sp<Client> client(mClientRef.promote()); 1144 1145 result.appendFormat( " " 1146 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 1147 "isOpaque=%1d, invalidate=%1d, " 1148 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 1149 " client=%p\n", 1150 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 1151 s.active.crop.left, s.active.crop.top, 1152 s.active.crop.right, s.active.crop.bottom, 1153 isOpaque(), contentDirty, 1154 s.alpha, s.flags, 1155 s.transform[0][0], s.transform[0][1], 1156 s.transform[1][0], s.transform[1][1], 1157 client.get()); 1158 1159 sp<const GraphicBuffer> buf0(mActiveBuffer); 1160 uint32_t w0=0, h0=0, s0=0, f0=0; 1161 if (buf0 != 0) { 1162 w0 = buf0->getWidth(); 1163 h0 = buf0->getHeight(); 1164 s0 = buf0->getStride(); 1165 f0 = buf0->format; 1166 } 1167 result.appendFormat( 1168 " " 1169 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 1170 " queued-frames=%d, mRefreshPending=%d\n", 1171 mFormat, w0, h0, s0,f0, 1172 mQueuedFrames, mRefreshPending); 1173 1174 if (mSurfaceFlingerConsumer != 0) { 1175 mSurfaceFlingerConsumer->dump(result, " "); 1176 } 1177} 1178 1179void Layer::dumpStats(String8& result) const { 1180 mFrameTracker.dump(result); 1181} 1182 1183void Layer::clearStats() { 1184 mFrameTracker.clear(); 1185} 1186 1187void Layer::logFrameStats() { 1188 mFrameTracker.logAndResetStats(mName); 1189} 1190 1191// --------------------------------------------------------------------------- 1192 1193Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 1194 const sp<Layer>& layer) 1195 : mFlinger(flinger), mLayer(layer) { 1196} 1197 1198Layer::LayerCleaner::~LayerCleaner() { 1199 // destroy client resources 1200 mFlinger->onLayerDestroyed(mLayer); 1201} 1202 1203// --------------------------------------------------------------------------- 1204}; // namespace android 1205 1206#if defined(__gl_h_) 1207#error "don't include gl/gl.h in this file" 1208#endif 1209 1210#if defined(__gl2_h_) 1211#error "don't include gl2/gl2.h in this file" 1212#endif 1213