Layer.cpp revision 65476f3332641066a99e22338bf5cf49ce4af642
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> 30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h> 3890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 44b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h" 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h" 481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 50875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1; 5813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, 604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags) 6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : contentDirty(false), 6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sequence(uint32_t(android_atomic_inc(&sSequence))), 6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger(flinger), 64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mTextureName(-1U), 6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mPremultipliedAlpha(true), 6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mName("unnamed"), 6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat(PIXEL_FORMAT_NONE), 6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mTransactionFlags(0), 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mQueuedFrames(0), 70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSidebandStreamChanged(false), 71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentTransform(0), 72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity(true), 744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending(false), 7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyNeeded(false), 7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering(false), 7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mNeedsFiltering(false), 785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), 79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp(false), 8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mHasSurface(false), 8203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews mClientRef(client), 83a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mPotentialCursor(false), 84a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mQueueItemLock(), 85a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mQueueItemCondition(), 86a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mQueueItems(), 8765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza mLastFrameNumberReceived(0), 8865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza mUpdateTexImageFailed(false) 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 90a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian mFlinger->getRenderEngine().genTextures(1, &mTextureName); 9249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); 934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t layerFlags = 0; 954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eHidden) 964125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden layerFlags |= layer_state_t::eLayerHidden; 974125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (flags & ISurfaceComposerClient::eOpaque) 984125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden layerFlags |= layer_state_t::eLayerOpaque; 994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eNonPremultiplied) 1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mPremultipliedAlpha = false; 1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mName = name; 1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.w = w; 1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.h = h; 1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.crop.makeInvalid(); 1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.z = 0; 1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.alpha = 0xFF; 1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.layerStack = 0; 1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.flags = layerFlags; 1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.sequence = 0; 1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.transform.set(0, 0); 1144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.requested = mCurrentState.active; 1154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian // drawing state & current state are identical 1174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mDrawingState = mCurrentState; 1186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis nsecs_t displayPeriod = 1206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 1216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.setDisplayRefreshPeriod(displayPeriod); 122e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 123e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() { 125bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 126b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza sp<IGraphicBufferProducer> producer; 127b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza sp<IGraphicBufferConsumer> consumer; 128b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer); 129b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza mProducer = new MonitoredProducer(producer, mFlinger); 130b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName); 131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 132399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSurfaceFlingerConsumer->setContentsChangedListener(this); 1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mSurfaceFlingerConsumer->setName(mName); 134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1357f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1367f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 137bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 1387f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 139bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 140303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 1416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 1428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 1438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian updateTransformHint(hw); 144b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 14596f0819f81293076e652792794a961543e6750d7Mathias Agopian 1464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() { 14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> c(mClientRef.promote()); 14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (c != 0) { 14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian c->detachLayer(this); 15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 151921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 1526547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 15396f0819f81293076e652792794a961543e6750d7Mathias Agopian} 15496f0819f81293076e652792794a961543e6750d7Mathias Agopian 15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks 15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 159c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, 16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWComposer::HWCLayerInterface* layer) { 16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer) { 16213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer->onDisplayed(); 16313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); 16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 16613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 1676b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) { 1686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Add this buffer from our internal queue tracker 1696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza { // Autolock scope 1706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 171a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 172a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // Reset the frame number tracker when we receive the first buffer after 173a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // a frame number reset 174a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza if (item.mFrameNumber == 1) { 175a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mLastFrameNumberReceived = 0; 176a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 177a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 178a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // Ensure that callbacks are handled in order 179a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza while (item.mFrameNumber != mLastFrameNumberReceived + 1) { 180a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, 181a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza ms2ns(500)); 182a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza if (result != NO_ERROR) { 183a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza ALOGE("[%s] Timed out waiting on callback", mName.string()); 184a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 185a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 186a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 1876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.push_back(item); 188ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza android_atomic_inc(&mQueuedFrames); 189a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 190a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // Wake up any pending callbacks 191a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mLastFrameNumberReceived = item.mFrameNumber; 192a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mQueueItemCondition.broadcast(); 1936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1946b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 196579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 197579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 1986b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) { 1996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 200a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 201a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // Ensure that callbacks are handled in order 202a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza while (item.mFrameNumber != mLastFrameNumberReceived + 1) { 203a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, 204a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza ms2ns(500)); 205a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza if (result != NO_ERROR) { 206a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza ALOGE("[%s] Timed out waiting on callback", mName.string()); 207a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 208a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 209a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 2106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (mQueueItems.empty()) { 2116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza ALOGE("Can't replace a frame on an empty queue"); 2126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return; 2136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 2146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.editItemAt(0) = item; 215a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 216a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza // Wake up any pending callbacks 217a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mLastFrameNumberReceived = item.mFrameNumber; 218a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mQueueItemCondition.broadcast(); 2196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza} 2206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 221399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() { 222399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { 223399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // mSidebandStreamChanged was false 224399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mFlinger->signalLayerUpdate(); 225399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 226399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 227399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 2286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after 2296710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before 2306710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list) 23113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() { 232bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->abandon(); 23348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 234cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up 23713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 23813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const { 24013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mName; 24113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 24213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 24313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 24413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian PixelFormat format, uint32_t flags) 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t const maxSurfaceDims = min( 24713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 24813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 24913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // never allow a surface larger than what our underlying GL implementation 25013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // can handle. 25113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 25213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 25313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return BAD_VALUE; 25413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 25513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 25613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat = format; 25713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 25803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false; 25913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 26013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 26113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentOpacity = getOpacityForFormat(format); 26213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return NO_ERROR; 26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() { 2714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Mutex::Autolock _l(mLock); 2724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian LOG_ALWAYS_FATAL_IF(mHasSurface, 2744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian "Layer::getHandle() has already been called"); 2754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mHasSurface = true; 2774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 278882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden /* 2794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * The layer handle is just a BBinder object passed to the client 2804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * (remote process) -- we don't keep any reference on our side such that 2814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * the dtor is called when the remote side let go of its reference. 282882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * 2834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for 2844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * this layer when the handle is destroyed. 285882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden */ 2864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian class Handle : public BBinder, public LayerCleaner { 288a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 289a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) 2914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { 2924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian } 293a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return new Handle(mFlinger, this); 296582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 297582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 298b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const { 299b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza return mProducer; 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up 30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 306a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const { 307a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // this is the crop rectangle that applies to the buffer 308a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // itself (as opposed to the window) 309f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 310f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 311a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if the buffer crop is defined, we use that 312f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 313a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian } else if (mActiveBuffer != NULL) { 314a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // otherwise we use the whole buffer 315a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian crop = mActiveBuffer->getBounds(); 316f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 317a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if we don't have a buffer yet, we use an empty/invalid crop 3184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 319f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 320f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 321f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 322f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 323f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) { 324f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (CC_LIKELY(exclude.isEmpty())) { 325f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win; 326f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 327f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (exclude.isRect()) { 328f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win.reduce(exclude.getBounds()); 329f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 330f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return Region(win).subtract(exclude).getBounds(); 331f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian} 332f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 33313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const { 3341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 3356c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine return computeBounds(s.activeTransparentRegion); 3366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine} 3376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine 3386c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const { 3396c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine const Layer::State& s(getDrawingState()); 34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 3446c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 3456c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine return reduce(win, activeTransparentRegion); 34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3486b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { 34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the content crop is the area of the content that gets scaled to the 35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layer's size. 3516b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian FloatRect crop(getContentCrop()); 35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the active.crop is the area of the window that gets cropped, but not 35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // scaled in any ways. 3551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the projection's clipping to the window crop in 35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layerstack space, and convert-back to layer space. 3596b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // if there are no window scaling involved, this operation will map to full 3606b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // pixels in the buffer. 3616b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // FIXME: the 3 lines below can produce slightly incorrect clipping when we have 3626b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // a viewport clipping and a window transform. we should use floating point to fix this. 3630e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian 3640e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian Rect activeCrop(s.active.w, s.active.h); 3650e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian if (!s.active.crop.isEmpty()) { 3660e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian activeCrop = s.active.crop; 3670e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian } 3680e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian 3690e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian activeCrop = s.transform.transform(activeCrop); 37013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(hw->getViewport(), &activeCrop); 37113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop = s.transform.inverse().transform(activeCrop); 37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 37328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // This needs to be here as transform.transform(Rect) computes the 37428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transformed rect and then takes the bounding box of the result before 37528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // returning. This means 37628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transform.inverse().transform(transform.transform(Rect)) != Rect 37728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // in which case we need to make sure the final rect is clipped to the 37828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // display bounds. 37913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 38013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 381f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian // subtract the transparent region and snap to the bounds 382f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian activeCrop = reduce(activeCrop, s.activeTransparentRegion); 383f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 38413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!activeCrop.isEmpty()) { 38513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Transform the window crop to match the buffer coordinate system, 38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // which means using the inverse of the current transform set on the 38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // SurfaceFlingerConsumer. 3886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian uint32_t invTransform = mCurrentTransform; 389f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 390f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine /* 391f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine * the code below applies the display's inverse transform to the buffer 392f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine */ 393f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine uint32_t invTransformOrient = hw->getOrientationTransform(); 394f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine // calculate the inverse transform 395f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) { 396f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 397f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 3981440963470cda68be762957e2efb7ecbe1570366Michael Lentine // If the transform has been rotated the axis of flip has been swapped 3991440963470cda68be762957e2efb7ecbe1570366Michael Lentine // so we need to swap which flip operations we are performing 4001440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 4011440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 4021440963470cda68be762957e2efb7ecbe1570366Michael Lentine if (is_h_flipped != is_v_flipped) { 4031440963470cda68be762957e2efb7ecbe1570366Michael Lentine invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 4041440963470cda68be762957e2efb7ecbe1570366Michael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 4051440963470cda68be762957e2efb7ecbe1570366Michael Lentine } 406f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine } 407f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine // and apply to the current transform 408f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation(); 409f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine } 410f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine 41113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winWidth = s.active.w; 41213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winHeight = s.active.h; 41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 4147b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // If the activeCrop has been rotate the ends are rotated but not 4157b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // the space itself so when transforming ends back we can't rely on 4167b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // a modification of the axes of rotation. To account for this we 4177b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // need to reorient the inverse rotation in terms of the current 4187b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // axes of rotation. 4197b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 4207b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 4217b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine if (is_h_flipped == is_v_flipped) { 4227b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 4237b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 4247b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine } 42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winWidth = s.active.h; 42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winHeight = s.active.w; 42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect winCrop = activeCrop.transform( 429f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransform, s.active.w, s.active.h); 43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 4316b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // below, crop is intersected with winCrop expressed in crop's coordinate space 4326b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float xScale = crop.getWidth() / float(winWidth); 4336b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float yScale = crop.getHeight() / float(winHeight); 43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 435f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetL = winCrop.left * xScale; 436f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetT = winCrop.top * yScale; 437f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetR = (winWidth - winCrop.right ) * xScale; 438f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetB = (winHeight - winCrop.bottom) * yScale; 43913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 44013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.left += insetL; 44113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.top += insetT; 44213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.right -= insetR; 44313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.bottom -= insetB; 44413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 44513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return crop; 44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 4484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 4494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<const DisplayDevice>& hw, 4504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 451a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 45213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setDefaultState(); 453a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 4543e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 4553e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 456a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 457dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (isSecure() && !hw->isSecure()) { 458dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis layer.setSkip(true); 459dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 460dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 46113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this gives us only the "orientation" component of the transform 4621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 4634125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (!isOpaque(s) || s.alpha != 0xFF) { 46413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setBlending(mPremultipliedAlpha ? 46513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_PREMULT : 46613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_COVERAGE); 46713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 46813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 46913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the layer's transform, followed by the display's global transform 47013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // here we're guaranteed that the layer's transform preserves rects 4716c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Region activeTransparentRegion(s.activeTransparentRegion); 4726c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine if (!s.active.crop.isEmpty()) { 4736c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Rect activeCrop(s.active.crop); 4746c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop = s.transform.transform(activeCrop); 4756c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop.intersect(hw->getViewport(), &activeCrop); 4766c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop = s.transform.inverse().transform(activeCrop); 47728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // This needs to be here as transform.transform(Rect) computes the 47828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transformed rect and then takes the bounding box of the result before 47928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // returning. This means 48028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transform.inverse().transform(transform.transform(Rect)) != Rect 48128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // in which case we need to make sure the final rect is clipped to the 48228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // display bounds. 48328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 4846c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine // mark regions outside the crop as transparent 4856c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top)); 4866c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, 4876c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine s.active.w, s.active.h)); 4886c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, activeCrop.top, 4896c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop.left, activeCrop.bottom)); 4906c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top, 4916c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine s.active.w, activeCrop.bottom)); 4926c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine } 4936c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Rect frame(s.transform.transform(computeBounds(activeTransparentRegion))); 49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian frame.intersect(hw->getViewport(), &frame); 49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr(hw->getTransform()); 49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setFrame(tr.transform(frame)); 49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setCrop(computeCrop(hw)); 4989f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian layer.setPlaneAlpha(s.alpha); 4999f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian 50029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 50129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 50229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 50329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 50429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 50529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 50629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 50729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 50829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 509c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian Transform transform(tr * s.transform * bufferOrientation); 510c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 511c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 512c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian /* 513c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * the code below applies the display's inverse transform to the buffer 514c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian */ 515c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian uint32_t invTransform = hw->getOrientationTransform(); 5161440963470cda68be762957e2efb7ecbe1570366Michael Lentine uint32_t t_orientation = transform.getOrientation(); 517c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // calculate the inverse transform 518c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 519c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 520c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian NATIVE_WINDOW_TRANSFORM_FLIP_H; 5211440963470cda68be762957e2efb7ecbe1570366Michael Lentine // If the transform has been rotated the axis of flip has been swapped 5221440963470cda68be762957e2efb7ecbe1570366Michael Lentine // so we need to swap which flip operations we are performing 5231440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 5241440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 5251440963470cda68be762957e2efb7ecbe1570366Michael Lentine if (is_h_flipped != is_v_flipped) { 5261440963470cda68be762957e2efb7ecbe1570366Michael Lentine t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 5271440963470cda68be762957e2efb7ecbe1570366Michael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 5281440963470cda68be762957e2efb7ecbe1570366Michael Lentine } 529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // and apply to the current transform 5311440963470cda68be762957e2efb7ecbe1570366Michael Lentine transform = Transform(t_orientation) * Transform(invTransform); 532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 53329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 53429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 53513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t orientation = transform.getOrientation(); 53613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 53713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we can only handle simple transformation 5383e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 539a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 54013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setTransform(orientation); 541a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 542a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 543a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 5444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 545d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we have to set the visible region on every frame because 54713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we currently free it during onLayerDisplayed(), which is called 54813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // after HWComposer::commit() -- every frame. 54913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Apply this display's projection's viewport to the visible region 55013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // before giving it to the HWC HAL. 55113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr = hw->getTransform(); 55213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 55313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setVisibleRegionScreen(visible); 55413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 555ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza // Pass full-surface damage down untouched 556ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza if (surfaceDamageRegion.isRect() && 557ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) { 558ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer.setSurfaceDamage(surfaceDamageRegion); 559ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 560ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza Region surfaceDamage = 561ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza tr.transform(surfaceDamageRegion.intersect(hw->getViewport())); 562ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer.setSurfaceDamage(surfaceDamage); 563ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 564ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza 565399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (mSidebandStream.get()) { 566399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall layer.setSidebandStream(mSidebandStream); 567399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } else { 568399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // NOTE: buffer can be NULL if the client never drew into this 569399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // layer yet, or if we ran out of memory 570399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall layer.setBuffer(mActiveBuffer); 571399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 572c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 573dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 574c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, 575d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 576c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 577d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 578d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // TODO: there is a possible optimization here: we only need to set the 579d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // acquire fence the first time a new buffer is acquired on EACH display. 580d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 58103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { 582bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 5831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (fence->isValid()) { 584c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 585dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 586dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 587dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 588dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 589dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 590c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 591c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 592c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 59303414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition( 59403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<const DisplayDevice>& hw) 59503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 59603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // this gives us only the "orientation" component of the transform 59703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const State& s(getCurrentState()); 59803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 59903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // apply the layer's transform, followed by the display's global transform 60003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // here we're guaranteed that the layer's transform preserves rects 60103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect win(s.active.w, s.active.h); 60203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (!s.active.crop.isEmpty()) { 60303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews win.intersect(s.active.crop, &win); 60403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 60503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // subtract the transparent region and snap to the bounds 60603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect bounds = reduce(win, s.activeTransparentRegion); 60703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect frame(s.transform.transform(bounds)); 60803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews frame.intersect(hw->getViewport(), &frame); 60903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Transform& tr(hw->getTransform()); 61003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews return Rect(tr.transform(frame)); 61103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 61203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 61313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing... 61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 618c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, clip, false); 61913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 62013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 621c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw, 622c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const { 623c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, Region(hw->bounds()), useIdentityTransform); 62413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 62513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const { 627c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, Region(hw->bounds()), false); 628c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza} 629c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza 630c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip, 631c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 6331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 635a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 637179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 638179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 639179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 640179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 641179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 642179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 643179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 644179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 645179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 646f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 647f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 648179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 649179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(drawingLayers[i]); 65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer.get() == static_cast<Layer const*>(this)) 652179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 6534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 654179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 655179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 656179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 657179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 6581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 659179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 66397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the current buffer to the GL texture, and wait for it to be 66497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // ready for us to draw into. 665bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 666bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 66797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 668dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 669dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 670dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 671dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 672dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 673dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 674875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 675875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 676dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (!blackOutLayer) { 677cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 678eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 679cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 680cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 681cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 682bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 683bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 684cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 685c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 686c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 687c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian /* 688c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * the code below applies the display's inverse transform to the texture transform 689c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian */ 690c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 691c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // create a 4x4 transform matrix from the display transform flags 692c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); 693c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); 694c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); 695c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 696c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian mat4 tr; 697c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian uint32_t transform = hw->getOrientationTransform(); 698c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) 699c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * rot90; 700c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) 701c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * flipH; 702c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) 703c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * flipV; 704c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 705c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // calculate the inverse 706c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = inverse(tr); 707c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 708c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // and finally apply it to the original texture matrix 709c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr); 710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix)); 711c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 712c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 713cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 71449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 71549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setFiltering(useFiltering); 71649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setMatrix(textureMatrix); 71749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian 71849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian engine.setupLayerTexturing(mTexture); 719a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 720875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.setupLayerBlackedOut(); 721a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 722c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza drawWithOpenGL(hw, clip, useIdentityTransform); 723875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableTexturing(); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 727c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, 728c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Region& /* clip */, float red, float green, float blue, 729c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza float alpha) const 73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 73119733a32799f792125913e746e8644d16f8dc223Mathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 732c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza computeGeometry(hw, mMesh, false); 73319733a32799f792125913e746e8644d16f8dc223Mathias Agopian engine.setupFillWithColor(red, green, blue, alpha); 73419733a32799f792125913e746e8644d16f8dc223Mathias Agopian engine.drawMesh(mMesh); 73513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 73613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL( 73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<const DisplayDevice>& hw, const Region& clip) const { 73913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian clearWithOpenGL(hw, clip, 0,0,0,0); 74013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 74113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 742c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw, 743c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Region& /* clip */, bool useIdentityTransform) const { 7441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 746c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza computeGeometry(hw, mMesh, useIdentityTransform); 74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian /* 74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * NOTE: the way we compute the texture coordinates here produces 75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * different results than when we take the HWC path -- in the later case 75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * the "source crop" is rounded to texel boundaries. 75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * This can produce significantly different results when the texture 75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * is scaled by a large amount. 75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * 75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * The GL code below is more logical (imho), and the difference with 75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * HWC is due to a limitation of the HWC API to integers -- a question 757c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * is suspend is whether we should ignore this problem or revert to 75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * GL composition when a buffer scaling is applied (maybe with some 75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * minimal value)? Or, we could make GL behave like HWC -- but this feel 76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * like more of a hack. 76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian */ 76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect win(computeBounds()); 76313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float left = float(win.left) / float(s.active.w); 7653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float top = float(win.top) / float(s.active.h); 7663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float right = float(win.right) / float(s.active.w); 7673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float bottom = float(win.bottom) / float(s.active.h); 76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 769875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // TODO: we probably want to generate the texture coords with the mesh 770875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // here we assume that we only have 4 vertices 771ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); 772ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[0] = vec2(left, 1.0f - top); 773ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[1] = vec2(left, 1.0f - bottom); 774ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[2] = vec2(right, 1.0f - bottom); 775ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[3] = vec2(right, 1.0f - top); 77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 777875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 7784125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); 7795cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian engine.drawMesh(mMesh); 780875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableBlending(); 78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7831681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const { 7841681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk int producerStickyTransform = 0; 7851681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform); 7861681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk if (ret != OK) { 7871681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__, 7881681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk strerror(-ret), ret); 7891681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk return 0; 7901681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk } 7911681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk return static_cast<uint32_t>(producerStickyTransform); 7921681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk} 7931681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) { 79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering = filtering; 79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const { 79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mFiltering; 80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 802ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 803ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 804ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 805ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 806ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 807ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 808ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 8095773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) { 810a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 811a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 812ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 8135773d3f5b2694c647e010246dff99acc70131289Mathias Agopian switch (format) { 8145773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 8155773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_BGRA_8888: 816dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return false; 8175773d3f5b2694c647e010246dff99acc70131289Mathias Agopian } 8185773d3f5b2694c647e010246dff99acc70131289Mathias Agopian // in all other case, we have no blending (also for unknown formats) 819dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return true; 820ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 821ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state 82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 826c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh, 827c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const 82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 8291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 830c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Transform tr(useIdentityTransform ? 831c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza hw->getTransform() : hw->getTransform() * s.transform); 83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t hw_h = hw->getHeight(); 83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 8376c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 838f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian win = reduce(win, s.activeTransparentRegion); 8393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 840ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 841ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[0] = tr.transform(win.left, win.top); 842ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[1] = tr.transform(win.left, win.bottom); 843ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[2] = tr.transform(win.right, win.bottom); 844ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[3] = tr.transform(win.right, win.top); 8453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian for (size_t i=0 ; i<4 ; i++) { 8465cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i].y = hw_h - position[i].y; 84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 849ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 8504125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const 851a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 852a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 853a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 854db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 855a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 856db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 857a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 858a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 859a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 8604125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity; 861a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 862a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 8637a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 8647a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 865a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 8667a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 8677a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 8687a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 869b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const { 87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const { 87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !mCurrentCrop.isEmpty(); 87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mNeedsFiltering || hw->needsFiltering(); 88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) { 88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleRegion = visibleRegion; 88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 88613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 88713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) { 88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 88913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->coveredRegion = coveredRegion; 89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region& 89313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setVisibleNonTransparentRegion) { 89413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 89813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction 90013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 90113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 90213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) { 9031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 9041c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 9051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 9061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& c(getCurrentState()); 907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool sizeChanged = (c.requested.w != s.requested.w) || 9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != s.requested.h); 910a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 911a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 912cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 9139d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 9146905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 915419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 916419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 917419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 918419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 9191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian this, getName().string(), mCurrentTransform, mCurrentScalingMode, 9201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.w, c.active.h, 9211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.left, 9221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.top, 9231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.right, 9241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.bottom, 9251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getWidth(), 9261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getHeight(), 9271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h, 9281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.left, 9291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.top, 9301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.right, 9311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.bottom, 9321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getWidth(), 9331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getHeight(), 9341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.w, s.active.h, 9351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.left, 9361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.top, 9371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.right, 9381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.bottom, 9391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getWidth(), 9401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getHeight(), 9411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.w, s.requested.h, 9421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.left, 9431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.top, 9441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.right, 9451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.bottom, 9461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getWidth(), 9471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getHeight()); 948a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 9492a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 9502a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 951bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferSize( 9521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h); 953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 954cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 9550cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 9560cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool resizePending = (c.requested.w != c.active.w) || 9581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != c.active.h); 9590cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9609e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza if (resizePending && mSidebandStream == NULL) { 96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // don't let Layer::doTransaction update the drawing state 9620cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 9630cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 9640cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 9650cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 9660cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 9670cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 9680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 9699e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza // 9709e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza // If a sideband stream is attached, however, we want to skip this 9719e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza // optimization so that transactions aren't missed when a buffer 9729e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza // never arrives 9730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 9750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 9760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 9770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always set active to requested, unless we're asked not to 97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this is used by Layer, which special cases resizes. 98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (flags & eDontUpdateGeometryState) { 98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } else { 9821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Layer::State& editCurrentState(getCurrentState()); 9831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian editCurrentState.active = c.requested; 98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 9861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (s.active != c.active) { 98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= Layer::eVisibleRegion; 98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 9911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (c.sequence != s.sequence) { 99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= eVisibleRegion; 99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->contentDirty = true; 99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we may use linear filtering, if the matrix scales us 9971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const uint8_t type = c.transform.getType(); 9981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian mNeedsFiltering = (!c.transform.preserveRects() || 99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian (type >= Transform::SCALE)); 100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Commit the transaction 100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian commitTransaction(); 100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return flags; 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() { 100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mDrawingState = mCurrentState; 1009a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 1010a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) { 101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_and(~flags, &mTransactionFlags) & flags; 101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) { 101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_or(flags, &mTransactionFlags); 101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) { 102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set(x, y); 102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 102513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) { 102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.z == z) 102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.z = z; 103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) { 103613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 103813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.w = w; 103913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.h = h; 104013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) { 104413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.alpha == alpha) 104513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 104613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.alpha = alpha; 104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 104913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 105013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 105113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 105213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 105313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set( 105413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 105513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 105613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 105713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 105813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) { 10592ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian mCurrentState.requestedTransparentRegion = transparent; 106013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 106113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 106213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 106313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) { 106413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 106513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.flags == newFlags) 106613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 106713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 106813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.flags = newFlags; 106913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 107013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 107113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 107213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) { 107313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.crop == crop) 107413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 107513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 107613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.crop = crop; 107713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 107813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 107913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 108013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 108113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) { 108213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.layerStack == layerStack) 108313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 108413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 108513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.layerStack = layerStack; 108613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 108713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 1088a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 1089a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 1090ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() { 1091ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza if (mFlinger->mForceFullDamage) { 1092ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza surfaceDamageRegion = Region::INVALID_REGION; 1093ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1094ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); 1095ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 1096ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza} 1097ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza 1098ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() { 1099ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza surfaceDamageRegion.clear(); 1100ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza} 1101ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11066b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const { 11076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza nsecs_t expectedPresent = 11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); 11106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return mQueueItems.empty() ? 11116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza false : mQueueItems[0].mTimestamp < expectedPresent; 11126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza} 11136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 11144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 11154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 1116399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return mQueuedFrames > 0 || mSidebandStreamChanged; 111799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 111899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1119d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() { 1120d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (mFrameLatencyNeeded) { 1121bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 112282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setDesiredPresentTime(desiredPresentTime); 112382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1124bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 1125789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (frameReadyFence->isValid()) { 112682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyFence(frameReadyFence); 112782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 112882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // There was no fence for this frame, so assume that it was ready 112982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // to be presented at the desired present time. 113082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyTime(desiredPresentTime); 113182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 113282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1133d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const HWComposer& hwc = mFlinger->getHwComposer(); 113482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 1135789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (presentFence->isValid()) { 113682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentFence(presentFence); 113782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 113882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // The HWC doesn't support present fences, so use the refresh 113982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // timestamp instead. 114082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 114182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentTime(presentTime); 114282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 114382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 114482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.advanceFrame(); 1145d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyNeeded = false; 1146d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 1147d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian} 1148d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 1149da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const { 115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Layer::State& s(mDrawingState); 115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 1152afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim && (mActiveBuffer != NULL || mSidebandStream != NULL); 1153da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 1154da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 11554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 11581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 1159399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { 1160399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // mSidebandStreamChanged was true 1161399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); 116212e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza if (mSidebandStream != NULL) { 116312e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza setTransactionFlags(eTransactionNeeded); 116412e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza mFlinger->setTransactionFlags(eTraversalNeeded); 116512e0a27aa30d9db10eafe88904d3eb8fdcbcfa71Dan Stoza } 11665bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall recomputeVisibleRegions = true; 11675bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall 11685bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall const State& s(getDrawingState()); 11695bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall return s.transform.transform(Region(Rect(s.active.w, s.active.h))); 1170399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 1171399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 11724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 11733d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 117499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 117599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 117699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 117799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 117899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 117999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 11804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 11814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 118299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 118399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1184351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 11854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const State& s(getDrawingState()); 11864125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool oldOpacity = isOpaque(s); 1187351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 1188db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 1189bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 11902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 11912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 11922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 11931681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bool stickyTransformSet; 11942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 11951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bool& recomputeVisibleRegions, bool stickySet) 11962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 11971681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk recomputeVisibleRegions(recomputeVisibleRegions), 11981681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk stickyTransformSet(stickySet) { 11992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 120211611f9be590480d7ea27bf0153558573ddcded2Dan Stoza const BufferItem& item) { 12032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 12042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 12052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 12082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 12092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 12112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 12122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 12132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 12142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 12172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 12182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 12202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 12212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 12222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 12232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 12242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 12252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 12262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 12272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 12292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 12302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 12312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 12322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 12332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 12342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 12352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 12372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 12382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 12416905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 12422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 12432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 12446905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden bufWidth, bufHeight, item.mTransform, item.mScalingMode, 12452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 12462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 12472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 12482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 12492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 12502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 12512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 12522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 12532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 12542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 12552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 12562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 12572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 12582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 12592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12611681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk if (!isFixedSize && !stickyTransformSet) { 12622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 12632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 12644824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 12651681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}", 12661681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bufWidth, bufHeight, front.active.w, front.active.h); 12672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 12682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 12712ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // if the transparent region has changed (this test is 12722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // conservative, but that's fine, worst case we're doing 12732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // a bit of extra work), we latch the new one and we 12742ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // trigger a visible-region recompute. 12752ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian if (!front.activeTransparentRegion.isTriviallyEqual( 12762ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.requestedTransparentRegion)) { 12772ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.activeTransparentRegion = front.requestedTransparentRegion; 12786c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 12796c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // We also need to update the current state so that 12806c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // we don't end-up overwriting the drawing state with 12816c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // this stale current state during the next transaction 12826c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // 12836c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // NOTE: We don't need to hold the transaction lock here 12846c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // because State::active is only accessed from this thread. 12856c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian current.activeTransparentRegion = front.activeTransparentRegion; 12866c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 12876c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // recompute visible region 12882ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian recomputeVisibleRegions = true; 12892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian } 12902ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 12912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 12922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 12942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, 12961681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk getProducerStickyTransform() != 0); 12972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 1298a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza uint64_t maxFrameNumber = 0; 1299a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza { 1300a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza Mutex::Autolock lock(mQueueItemLock); 1301a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza maxFrameNumber = mLastFrameNumberReceived; 1302a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza } 1303a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza 130441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, 1305a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza mFlinger->mPrimaryDispSync, maxFrameNumber); 13061585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult == BufferQueue::PRESENT_LATER) { 13071585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Producer doesn't want buffer to be displayed yet. Signal a 13081585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // layer update so we check again at the next opportunity. 13091585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 13101585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden return outDirtyRegion; 1311ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) { 1312ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza // If the buffer has been rejected, remove it from the shadow queue 1313ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza // and return early 1314ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza Mutex::Autolock lock(mQueueItemLock); 1315ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza mQueueItems.removeAt(0); 1316ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza android_atomic_dec(&mQueuedFrames); 1317ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza return outDirtyRegion; 131865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) { 131965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // This can occur if something goes wrong when trying to create the 132065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // EGLImage for this buffer. If this happens, the buffer has already 132165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // been released, so we need to clean up the queue and bug out 132265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // early. 132365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza { 132465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza Mutex::Autolock lock(mQueueItemLock); 132565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza mQueueItems.clear(); 132665476f3332641066a99e22338bf5cf49ce4af642Dan Stoza android_atomic_and(0, &mQueuedFrames); 132765476f3332641066a99e22338bf5cf49ce4af642Dan Stoza } 132865476f3332641066a99e22338bf5cf49ce4af642Dan Stoza 132965476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // Once we have hit this state, the shadow queue may no longer 133065476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // correctly reflect the incoming BufferQueue's contents, so even if 133165476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // updateTexImage starts working, the only safe course of action is 133265476f3332641066a99e22338bf5cf49ce4af642Dan Stoza // to continue to ignore updates. 133365476f3332641066a99e22338bf5cf49ce4af642Dan Stoza mUpdateTexImageFailed = true; 133465476f3332641066a99e22338bf5cf49ce4af642Dan Stoza 133565476f3332641066a99e22338bf5cf49ce4af642Dan Stoza return outDirtyRegion; 13361585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 13371585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 13386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza { // Autolock scope 1339ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); 1340ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza 13416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 1342ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza 1343ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza // Remove any stale buffers that have been dropped during 1344ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza // updateTexImage 1345ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza while (mQueueItems[0].mFrameNumber != currentFrameNumber) { 1346ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza mQueueItems.removeAt(0); 1347ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza android_atomic_dec(&mQueuedFrames); 1348ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza } 1349ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza 13506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.removeAt(0); 13516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 13526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 1353ecc504043fddb7a75042ce402c67aedfac04d5e2Dan Stoza 13541585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Decrement the queued-frames count. Signal another event if we 13551585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // have more frames pending. 13561585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (android_atomic_dec(&mQueuedFrames) > 1) { 13571585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 13581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 13591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 13601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult != NO_ERROR) { 1361a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 1362a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 13634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1364a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 1365d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 1366351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 1367bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1368e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 1369e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 13704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1371e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 1372da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 13734824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 1374702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 1375e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 13762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 13772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 1378ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 13792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 1380702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1381bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1382bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1383bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1384702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 1385702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 1386702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 1387702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 1388702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 1389702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 1390702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 1391ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1392702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1393702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1394702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 1395e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 1396e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 1397702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 1398702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 1399ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1400702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1401702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1402702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1403702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 14044125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (oldOpacity != isOpaque(s)) { 1405702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 1406702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1407702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 14084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 14091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Region dirtyRegion(Rect(s.active.w, s.active.h)); 14101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 14114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 14121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian outDirtyRegion = (s.transform.transform(dirtyRegion)); 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 141713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 141813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 141913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // TODO: should we do something special if mSecure is set? 142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mProtectedByApp) { 142113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // need a hardware-protected path to external video sink 142213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 142313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 142403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (mPotentialCursor) { 142503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews usage |= GraphicBuffer::USAGE_CURSOR; 142603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 142713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_HW_COMPOSER; 142813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return usage; 142913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 143013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 143113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 143213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t orientation = 0; 143313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 143413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // The transform hint is used to improve performance, but we can 143513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // only have a single transform hint, it cannot 143613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply to all displays. 143713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& planeTransform(hw->getTransform()); 143813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = planeTransform.getOrientation(); 143913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = 0; 144113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 144213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 144313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setTransformHint(orientation); 144413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 144513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 144613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 144713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging 144813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 144913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 14503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const 14511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 14521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 145313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 14543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.colorize(result, Colorizer::GREEN); 145574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 145613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "+ %s %p (%s)\n", 145713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian getTypeId(), this, getName().string()); 14583e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 145913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 14602ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian s.activeTransparentRegion.dump(result, "transparentRegion"); 146113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian visibleRegion.dump(result, "visibleRegion"); 1462ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza surfaceDamageRegion.dump(result, "surfaceDamageRegion"); 146313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> client(mClientRef.promote()); 146413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 146574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( " " 146613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 146713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "isOpaque=%1d, invalidate=%1d, " 146813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 146913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian " client=%p\n", 147013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 147113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.left, s.active.crop.top, 147213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.right, s.active.crop.bottom, 14734125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden isOpaque(s), contentDirty, 147413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.alpha, s.flags, 147513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[0][0], s.transform[0][1], 147613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[1][0], s.transform[1][1], 147713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian client.get()); 14781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1479a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 1480a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 14811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 14821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 14831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 14841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 1485a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 14861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 148774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 14881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 1489ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 14906905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden " queued-frames=%d, mRefreshPending=%d\n", 1491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 14926905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mQueuedFrames, mRefreshPending); 14931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1494bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mSurfaceFlingerConsumer != 0) { 149574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mSurfaceFlingerConsumer->dump(result, " "); 1496bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 1497d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 1498d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 1499d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const { 1500d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.dumpStats(result); 150182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 150282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 1503d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() { 1504d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.clearStats(); 150525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 150625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 15076547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() { 15086547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 15096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 15106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1511d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const { 1512d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.getStats(outStats); 1513d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 1514d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 151513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 151613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 151713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 151813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer) 151913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : mFlinger(flinger), mLayer(layer) { 1520b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 1521b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 152213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() { 152313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // destroy client resources 152413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->onLayerDestroyed(mLayer); 1525a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 1526a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 15283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android 1529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 15313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 15323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 15353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 15363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 1537