Layer.cpp revision dd533712f8dd21c0dadfd5ce8a0ad85aa3e96ada
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 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 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> 2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h> 25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h> 26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 400f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 43a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h" 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h" 461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 47875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 48875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1; 5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, 584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags) 5913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : contentDirty(false), 6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sequence(uint32_t(android_atomic_inc(&sSequence))), 6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger(flinger), 62a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mTextureName(-1U), 6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mPremultipliedAlpha(true), 6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mName("unnamed"), 6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mDebug(false), 6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat(PIXEL_FORMAT_NONE), 6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mOpaqueLayer(true), 6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mTransactionFlags(0), 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mQueuedFrames(0), 70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentTransform(0), 71933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 72a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity(true), 734d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending(false), 7482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyNeeded(false), 7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering(false), 7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mNeedsFiltering(false), 77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp(false), 7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mHasSurface(false), 8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mClientRef(client) 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 83a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glGenTextures(1, &mTextureName); 844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t layerFlags = 0; 864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eHidden) 874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian layerFlags = layer_state_t::eLayerHidden; 884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eNonPremultiplied) 904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mPremultipliedAlpha = false; 914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mName = name; 934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.w = w; 954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.h = h; 964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.crop.makeInvalid(); 974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.z = 0; 984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.alpha = 0xFF; 994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.layerStack = 0; 1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.flags = layerFlags; 1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.sequence = 0; 1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.transform.set(0, 0); 1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.requested = mCurrentState.active; 1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian // drawing state & current state are identical 1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mDrawingState = mCurrentState; 1076547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1086547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis nsecs_t displayPeriod = 1096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 1106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.setDisplayRefreshPeriod(displayPeriod); 111e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 112e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef() 11496f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 115bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 1166710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger); 1178f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(bq, mTextureName, 1188f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian GL_TEXTURE_EXTERNAL_OES, false); 119b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 120bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 121bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFrameAvailableListener(this); 1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mSurfaceFlingerConsumer->setName(mName); 123b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1247f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1257f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 1277f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 128bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 129303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 1306905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 1318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 1328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian updateTransformHint(hw); 133b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 13496f0819f81293076e652792794a961543e6750d7Mathias Agopian 1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() { 13613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> c(mClientRef.promote()); 13713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (c != 0) { 13813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian c->detachLayer(this); 13913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 140921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 1416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 14296f0819f81293076e652792794a961543e6750d7Mathias Agopian} 14396f0819f81293076e652792794a961543e6750d7Mathias Agopian 14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks 14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWComposer::HWCLayerInterface* layer) { 15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer) { 15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer->onDisplayed(); 15213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); 15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 156a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() { 1573d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 159579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 160579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 1616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after 1626710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before 1636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list) 16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() { 165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->abandon(); 16648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 167cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up 17013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 17113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 1721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const { 17313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mName; 17413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 17513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 17613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian PixelFormat format, uint32_t flags) 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t const maxSurfaceDims = min( 18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // never allow a surface larger than what our underlying GL implementation 18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // can handle. 18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return BAD_VALUE; 18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat = format; 19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentOpacity = getOpacityForFormat(format); 19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return NO_ERROR; 20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() { 2044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Mutex::Autolock _l(mLock); 2054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian LOG_ALWAYS_FATAL_IF(mHasSurface, 2074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian "Layer::getHandle() has already been called"); 2084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mHasSurface = true; 2104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 211882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden /* 2124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * The layer handle is just a BBinder object passed to the client 2134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * (remote process) -- we don't keep any reference on our side such that 2144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * the dtor is called when the remote side let go of its reference. 215882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * 2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for 2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * this layer when the handle is destroyed. 218882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden */ 2194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian class Handle : public BBinder, public LayerCleaner { 221a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 222a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) 2244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { 2254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian } 226a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return new Handle(mFlinger, this); 229582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 230582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 2314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<BufferQueue> Layer::getBufferQueue() const { 2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return mSurfaceFlingerConsumer->getBufferQueue(); 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up 23713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 23813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 239a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const { 240a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // this is the crop rectangle that applies to the buffer 241a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // itself (as opposed to the window) 242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 244a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if the buffer crop is defined, we use that 245f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 246a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian } else if (mActiveBuffer != NULL) { 247a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // otherwise we use the whole buffer 248a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian crop = mActiveBuffer->getBounds(); 249f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 250a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if we don't have a buffer yet, we use an empty/invalid crop 2514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 252f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 254f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 255f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 256f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) { 257f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (CC_LIKELY(exclude.isEmpty())) { 258f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win; 259f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 260f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (exclude.isRect()) { 261f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win.reduce(exclude.getBounds()); 262f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 263f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return Region(win).subtract(exclude).getBounds(); 264f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian} 265f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 26613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const { 2671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 27113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 2726c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 273f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return reduce(win, s.activeTransparentRegion); 27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2766b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { 27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the content crop is the area of the content that gets scaled to the 27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layer's size. 2796b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian FloatRect crop(getContentCrop()); 28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the active.crop is the area of the window that gets cropped, but not 28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // scaled in any ways. 2831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the projection's clipping to the window crop in 28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layerstack space, and convert-back to layer space. 2876b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // if there are no window scaling involved, this operation will map to full 2886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // pixels in the buffer. 2896b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // FIXME: the 3 lines below can produce slightly incorrect clipping when we have 2906b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // a viewport clipping and a window transform. we should use floating point to fix this. 29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect activeCrop(s.transform.transform(s.active.crop)); 29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(hw->getViewport(), &activeCrop); 29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop = s.transform.inverse().transform(activeCrop); 29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // paranoia: make sure the window-crop is constrained in the 29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // window's bounds 29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 299f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian // subtract the transparent region and snap to the bounds 300f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian activeCrop = reduce(activeCrop, s.activeTransparentRegion); 301f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!activeCrop.isEmpty()) { 30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Transform the window crop to match the buffer coordinate system, 30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // which means using the inverse of the current transform set on the 30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // SurfaceFlingerConsumer. 3066b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian uint32_t invTransform = mCurrentTransform; 30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winWidth = s.active.w; 30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winHeight = s.active.h; 30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian NATIVE_WINDOW_TRANSFORM_FLIP_H; 31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winWidth = s.active.h; 31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winHeight = s.active.w; 31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect winCrop = activeCrop.transform( 31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian invTransform, s.active.w, s.active.h); 31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3186b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // below, crop is intersected with winCrop expressed in crop's coordinate space 3196b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float xScale = crop.getWidth() / float(winWidth); 3206b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float yScale = crop.getHeight() / float(winHeight); 32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3226b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float insetL = winCrop.left * xScale; 3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float insetT = winCrop.top * yScale; 3246b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float insetR = (winWidth - winCrop.right ) * xScale; 3256b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float insetB = (winHeight - winCrop.bottom) * yScale; 32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 32713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.left += insetL; 32813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.top += insetT; 32913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.right -= insetR; 33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.bottom -= insetB; 33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return crop; 33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 3364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<const DisplayDevice>& hw, 3374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 338a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 33913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setDefaultState(); 340a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 3413e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 3423e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 343a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 344dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (isSecure() && !hw->isSecure()) { 345dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis layer.setSkip(true); 346dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 347dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this gives us only the "orientation" component of the transform 3491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!isOpaque() || s.alpha != 0xFF) { 35113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setBlending(mPremultipliedAlpha ? 35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_PREMULT : 35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_COVERAGE); 35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 35513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the layer's transform, followed by the display's global transform 35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // here we're guaranteed that the layer's transform preserves rects 35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect frame(s.transform.transform(computeBounds())); 35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian frame.intersect(hw->getViewport(), &frame); 36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr(hw->getTransform()); 36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setFrame(tr.transform(frame)); 36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setCrop(computeCrop(hw)); 3639f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian layer.setPlaneAlpha(s.alpha); 3649f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian 36529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 36629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 36729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 36829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 36929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 37029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 37129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 37229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 37329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform transform(tr * s.transform * bufferOrientation); 37529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 37629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t orientation = transform.getOrientation(); 37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we can only handle simple transformation 3803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 381a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 38213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setTransform(orientation); 383a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 384a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 385a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 3864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 387d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we have to set the visible region on every frame because 38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we currently free it during onLayerDisplayed(), which is called 39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // after HWComposer::commit() -- every frame. 39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Apply this display's projection's viewport to the visible region 39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // before giving it to the HWC HAL. 39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr = hw->getTransform(); 39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 39513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setVisibleRegionScreen(visible); 39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3973e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 3983e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // layer yet, or if we ran out of memory 39971e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian layer.setBuffer(mActiveBuffer); 400c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 401dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 4024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 403d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 404c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 405d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 406d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // TODO: there is a possible optimization here: we only need to set the 407d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // acquire fence the first time a new buffer is acquired on EACH display. 408d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 409d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (layer.getCompositionType() == HWC_OVERLAY) { 410bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 4111df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (fence->isValid()) { 412c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 413dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 414dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 415dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 416dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 417dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 418c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 419c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 420c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 42113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 42213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing... 42313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 42413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian onDraw(hw, clip); 42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw) { 43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian onDraw( hw, Region(hw->bounds()) ); 43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 4334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 437a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 439179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 440179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 441179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 442179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 443179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 444179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 445179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 446179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 447179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 448f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 449f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 450179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 451179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 45213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(drawingLayers[i]); 45313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer.get() == static_cast<Layer const*>(this)) 454179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 4554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 456179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 457179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 458179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 459179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 4601b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 461179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 464a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 46597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the current buffer to the GL texture, and wait for it to be 46697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // ready for us to draw into. 467bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 468bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 46997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 470dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 471dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 472dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 473dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 474dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 475dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 476875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 477875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (!blackOutLayer) { 479cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 480eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 481cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 482cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 483cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 484bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 485bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 486cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 487cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix); 489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 490875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.setupLayerBlackedOut(); 491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 4921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian drawWithOpenGL(hw, clip); 493875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableTexturing(); 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, 49813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const 49913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 50013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian LayerMesh mesh; 50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian computeGeometry(hw, &mesh); 50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 503875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mFlinger->getRenderEngine().clearWithColor( 504875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mesh.getVertices(), mesh.getVertexCount(), 505875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian red, green, blue, alpha); 50613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 50713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 50813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL( 50913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<const DisplayDevice>& hw, const Region& clip) const { 51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian clearWithOpenGL(hw, clip, 0,0,0,0); 51113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::drawWithOpenGL( 51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<const DisplayDevice>& hw, const Region& clip) const { 51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t fbHeight = hw->getHeight(); 5161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 51813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian LayerMesh mesh; 51913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian computeGeometry(hw, &mesh); 52013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 52113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian /* 52213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * NOTE: the way we compute the texture coordinates here produces 52313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * different results than when we take the HWC path -- in the later case 52413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * the "source crop" is rounded to texel boundaries. 52513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * This can produce significantly different results when the texture 52613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * is scaled by a large amount. 52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * 52813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * The GL code below is more logical (imho), and the difference with 52913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * HWC is due to a limitation of the HWC API to integers -- a question 53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * is suspend is wether we should ignore this problem or revert to 53113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * GL composition when a buffer scaling is applied (maybe with some 53213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * minimal value)? Or, we could make GL behave like HWC -- but this feel 53313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * like more of a hack. 53413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian */ 53513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect win(computeBounds()); 53613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 53713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian GLfloat left = GLfloat(win.left) / GLfloat(s.active.w); 53813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian GLfloat top = GLfloat(win.top) / GLfloat(s.active.h); 53913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian GLfloat right = GLfloat(win.right) / GLfloat(s.active.w); 54013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h); 54113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 542875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // TODO: we probably want to generate the texture coords with the mesh 543875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // here we assume that we only have 4 vertices 544875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian float texCoords[4][2]; 545875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[0][0] = left; 546875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[0][1] = top; 547875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[1][0] = left; 548875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[1][1] = bottom; 549875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[2][0] = right; 550875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[2][1] = bottom; 551875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[3][0] = right; 552875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[3][1] = top; 55313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian for (int i = 0; i < 4; i++) { 554875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian texCoords[i][1] = 1.0f - texCoords[i][1]; 55513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 557875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 558875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha); 559875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount()); 560875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableBlending(); 56113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 56213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 56313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) { 56413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering = filtering; 56513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 56713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const { 56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mFiltering; 56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 571ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 572ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 573ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 574ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 575ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 576ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 577ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 5785773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) { 579a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 580a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 581ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 5825773d3f5b2694c647e010246dff99acc70131289Mathias Agopian switch (format) { 5835773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 5845773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_BGRA_8888: 5855773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_RGBA_5551: 5865773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_RGBA_4444: 587dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return false; 5885773d3f5b2694c647e010246dff99acc70131289Mathias Agopian } 5895773d3f5b2694c647e010246dff99acc70131289Mathias Agopian // in all other case, we have no blending (also for unknown formats) 590dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return true; 591ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 592ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 59413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state 59513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 59613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 59713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const 59813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 5991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 60013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform tr(hw->getTransform() * s.transform); 60113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t hw_h = hw->getHeight(); 60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 6066c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 607f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian win = reduce(win, s.activeTransparentRegion); 60813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mesh) { 60913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian tr.transform(mesh->mVertices[0], win.left, win.top); 61013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian tr.transform(mesh->mVertices[1], win.left, win.bottom); 61113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian tr.transform(mesh->mVertices[2], win.right, win.bottom); 61213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian tr.transform(mesh->mVertices[3], win.right, win.top); 61313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian for (size_t i=0 ; i<4 ; i++) { 61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1]; 61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 618ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 619a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const 620a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 622a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 623db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 624a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 625db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mOpaqueLayer || mCurrentOpacity; 630a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 631a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 6327a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 6337a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 6357a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 6367a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 6377a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 638b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 63913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const { 64013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 64113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 64213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const { 64413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !mCurrentCrop.isEmpty(); 64513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 64613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 64713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 64813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mNeedsFiltering || hw->needsFiltering(); 64913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) { 65213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 65313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleRegion = visibleRegion; 65413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 65513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) { 65713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 65813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->coveredRegion = coveredRegion; 65913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 66013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 66113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region& 66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setVisibleNonTransparentRegion) { 66313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 66413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 66513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 66613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 66713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 66813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction 66913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 67013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 67113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) { 6721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6731c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 6751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& c(getCurrentState()); 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool sizeChanged = (c.requested.w != s.requested.w) || 6781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != s.requested.h); 679a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 680a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 681cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 6829d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 6836905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 684419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 685419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 686419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 687419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 6881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian this, getName().string(), mCurrentTransform, mCurrentScalingMode, 6891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.w, c.active.h, 6901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.left, 6911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.top, 6921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.right, 6931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.bottom, 6941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getWidth(), 6951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getHeight(), 6961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h, 6971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.left, 6981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.top, 6991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.right, 7001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.bottom, 7011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getWidth(), 7021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getHeight(), 7031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.w, s.active.h, 7041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.left, 7051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.top, 7061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.right, 7071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.bottom, 7081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getWidth(), 7091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getHeight(), 7101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.w, s.requested.h, 7111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.left, 7121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.top, 7131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.right, 7141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.bottom, 7151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getWidth(), 7161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getHeight()); 717a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 7182a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 7192a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 720bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferSize( 7211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h); 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 723cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 7240cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 7250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 7261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool resizePending = (c.requested.w != c.active.w) || 7271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != c.active.h); 7280cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 7290cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // don't let Layer::doTransaction update the drawing state 7310cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 7320cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 7330cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 7340cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 7350cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 7360cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 7370cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 7380cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 7390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 7400cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 7410cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 7420cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always set active to requested, unless we're asked not to 74413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this is used by Layer, which special cases resizes. 74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (flags & eDontUpdateGeometryState) { 74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } else { 7471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Layer::State& editCurrentState(getCurrentState()); 7481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian editCurrentState.active = c.requested; 74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (s.active != c.active) { 75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= Layer::eVisibleRegion; 75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (c.sequence != s.sequence) { 75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= eVisibleRegion; 75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->contentDirty = true; 76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we may use linear filtering, if the matrix scales us 7621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const uint8_t type = c.transform.getType(); 7631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian mNeedsFiltering = (!c.transform.preserveRects() || 76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian (type >= Transform::SCALE)); 76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Commit the transaction 76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian commitTransaction(); 76913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return flags; 770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() { 77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mDrawingState = mCurrentState; 774a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 775a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) { 77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_and(~flags, &mTransactionFlags) & flags; 77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) { 78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_or(flags, &mTransactionFlags); 78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) { 78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set(x, y); 78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 79113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) { 79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.z == z) 79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.z = z; 79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) { 80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 80213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 80313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.w = w; 80413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.h = h; 80513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 80613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 80713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) { 80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.alpha == alpha) 81013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 81113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 81213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.alpha = alpha; 81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set( 81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 82113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) { 8242ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian mCurrentState.requestedTransparentRegion = transparent; 82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) { 82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.flags == newFlags) 83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.flags = newFlags; 83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) { 83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.crop == crop) 83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.crop = crop; 84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) { 84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.layerStack == layerStack) 84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.layerStack = layerStack; 85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 853a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 854a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8594d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 8604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 8614d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return mQueuedFrames > 0; 86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 864d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() { 865d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (mFrameLatencyNeeded) { 866bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 86782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setDesiredPresentTime(desiredPresentTime); 86882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 869bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 870789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (frameReadyFence->isValid()) { 87182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyFence(frameReadyFence); 87282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 87382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // There was no fence for this frame, so assume that it was ready 87482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // to be presented at the desired present time. 87582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyTime(desiredPresentTime); 87682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 87782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 878d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const HWComposer& hwc = mFlinger->getHwComposer(); 87982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 880789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (presentFence->isValid()) { 88182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentFence(presentFence); 88282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 88382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // The HWC doesn't support present fences, so use the refresh 88482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // timestamp instead. 88582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 88682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentTime(presentTime); 88782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 88882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 88982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.advanceFrame(); 890d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyNeeded = false; 891d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 892d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian} 893d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 894da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const { 89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Layer::State& s(mDrawingState); 89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian && (mActiveBuffer != NULL); 898da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 899da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 9004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9021c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 9031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 9044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 9053d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 90699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 90799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 90899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 90999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 91099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 91199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 9124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 91499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 91599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 916351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 917db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis const bool oldOpacity = isOpaque(); 918351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 919db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 920bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 9212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 9222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 9232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 9242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 9252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions) 9262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 9272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions(recomputeVisibleRegions) { 9282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 9312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const BufferQueue::BufferItem& item) { 9322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 9332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 9342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 9372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 9382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 9402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 9412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 9422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 9432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 9462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 9472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 9492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 9502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 9512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 9522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 9532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 9542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 9552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 9562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 9582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 9592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 9602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 9612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 9622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 9632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 9642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 9662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 9672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 9706905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 9712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 9722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 9736905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden bufWidth, bufHeight, item.mTransform, item.mScalingMode, 9742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 9752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 9762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 9772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 9782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 9792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 9802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 9812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 9822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 9832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 9842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 9852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 9862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 9872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 9882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 9902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (!isFixedSize) { 9912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 9922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 9934824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 9942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 9952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 9972ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 9982ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // if the transparent region has changed (this test is 9992ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // conservative, but that's fine, worst case we're doing 10002ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // a bit of extra work), we latch the new one and we 10012ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // trigger a visible-region recompute. 10022ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian if (!front.activeTransparentRegion.isTriviallyEqual( 10032ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.requestedTransparentRegion)) { 10042ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.activeTransparentRegion = front.requestedTransparentRegion; 10056c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 10066c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // We also need to update the current state so that 10076c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // we don't end-up overwriting the drawing state with 10086c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // this stale current state during the next transaction 10096c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // 10106c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // NOTE: We don't need to hold the transaction lock here 10116c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // because State::active is only accessed from this thread. 10126c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian current.activeTransparentRegion = front.activeTransparentRegion; 10136c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 10146c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // recompute visible region 10152ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian recomputeVisibleRegions = true; 10162ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian } 10172ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 10182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 10192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 10202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 10212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 10222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 10231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions); 10242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 10251585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r); 10261585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult == BufferQueue::PRESENT_LATER) { 10271585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Producer doesn't want buffer to be displayed yet. Signal a 10281585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // layer update so we check again at the next opportunity. 10291585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 10301585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden return outDirtyRegion; 10311585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 10321585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 10331585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Decrement the queued-frames count. Signal another event if we 10341585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // have more frames pending. 10351585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (android_atomic_dec(&mQueuedFrames) > 1) { 10361585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 10371585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 10381585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 10391585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult != NO_ERROR) { 1040a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 1041a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 10424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1043a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 1044d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 1045351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 1046bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1047e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 1048e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 10494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1050e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 1051da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 10524824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 1053702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 1054e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 10552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 10562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 1057ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 10582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 1059702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1060bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1061bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1062bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1063702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 1064702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 1065702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 1066702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 1067702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 1068702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 1069702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 1070ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1071702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1072702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1073702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 1074e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 1075e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 1076702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 1077702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 1078ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1079702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1080702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1081702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1082702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 1083702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldOpacity != isOpaque()) { 1084702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 1085702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1086702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 10874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 10881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 10891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Region dirtyRegion(Rect(s.active.w, s.active.h)); 10901c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 10914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 10921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian outDirtyRegion = (s.transform.transform(dirtyRegion)); 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 109813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 109913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // TODO: should we do something special if mSecure is set? 110013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mProtectedByApp) { 110113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // need a hardware-protected path to external video sink 110213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 110313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 110413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_HW_COMPOSER; 110513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return usage; 110613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 110713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 110813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 110913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t orientation = 0; 111013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 111113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // The transform hint is used to improve performance, but we can 111213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // only have a single transform hint, it cannot 111313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply to all displays. 111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& planeTransform(hw->getTransform()); 111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = planeTransform.getOrientation(); 111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = 0; 111813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 111913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 112013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setTransformHint(orientation); 112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 112213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 112313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging 112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 112613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 11273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const 11281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 11291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 11313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.colorize(result, Colorizer::GREEN); 113274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "+ %s %p (%s)\n", 113413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian getTypeId(), this, getName().string()); 11353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 11372ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian s.activeTransparentRegion.dump(result, "transparentRegion"); 113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian visibleRegion.dump(result, "visibleRegion"); 113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> client(mClientRef.promote()); 114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 114174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( " " 114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "isOpaque=%1d, invalidate=%1d, " 114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 114513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian " client=%p\n", 114613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 114713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.left, s.active.crop.top, 114813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.right, s.active.crop.bottom, 114913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian isOpaque(), contentDirty, 115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.alpha, s.flags, 115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[0][0], s.transform[0][1], 115213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[1][0], s.transform[1][1], 115313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian client.get()); 11541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 1156a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 11571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 11581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 11591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 11601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 1161a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 11621b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 116374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 11641b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 1165ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 11666905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden " queued-frames=%d, mRefreshPending=%d\n", 1167a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 11686905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mQueuedFrames, mRefreshPending); 11691b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1170bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mSurfaceFlingerConsumer != 0) { 117174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mSurfaceFlingerConsumer->dump(result, " "); 1172bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 1173d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 1174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 117574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const { 117682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.dump(result); 117782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 117882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() { 118082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.clear(); 118125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 118225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 11836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() { 11846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 11856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 11866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 118913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer) 119113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : mFlinger(flinger), mLayer(layer) { 1192b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 1193b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 119413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() { 119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // destroy client resources 119613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->onLayerDestroyed(mLayer); 1197a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 1198a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 1199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 1203