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 mDebug(false), 6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat(PIXEL_FORMAT_NONE), 6913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mTransactionFlags(0), 70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mQueuedFrames(0), 71399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSidebandStreamChanged(false), 72a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentTransform(0), 73933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 74a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity(true), 754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending(false), 7682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyNeeded(false), 7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering(false), 7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mNeedsFiltering(false), 795cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), 80b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp(false), 8213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mHasSurface(false), 8303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews mClientRef(client), 8403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews mPotentialCursor(false) 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 86a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian mFlinger->getRenderEngine().genTextures(1, &mTextureName); 8849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); 894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t layerFlags = 0; 914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eHidden) 924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden layerFlags |= layer_state_t::eLayerHidden; 934125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (flags & ISurfaceComposerClient::eOpaque) 944125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden layerFlags |= layer_state_t::eLayerOpaque; 954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (flags & ISurfaceComposerClient::eNonPremultiplied) 974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mPremultipliedAlpha = false; 984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mName = name; 1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.w = w; 1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.h = h; 1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.active.crop.makeInvalid(); 1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.z = 0; 1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.alpha = 0xFF; 1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.layerStack = 0; 1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.flags = layerFlags; 1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.sequence = 0; 1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.transform.set(0, 0); 1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mCurrentState.requested = mCurrentState.active; 1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian // drawing state & current state are identical 1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mDrawingState = mCurrentState; 1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis nsecs_t displayPeriod = 1166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 1176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.setDisplayRefreshPeriod(displayPeriod); 118e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 119e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() { 121bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 122b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza sp<IGraphicBufferProducer> producer; 123b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza sp<IGraphicBufferConsumer> consumer; 124b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer); 125b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza mProducer = new MonitoredProducer(producer, mFlinger); 126b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName); 127bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 128399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSurfaceFlingerConsumer->setContentsChangedListener(this); 1294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mSurfaceFlingerConsumer->setName(mName); 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1317f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1327f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 133bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 1347f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 136303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 1376905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 1388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 1398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian updateTransformHint(hw); 140b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 14196f0819f81293076e652792794a961543e6750d7Mathias Agopian 1424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() { 14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> c(mClientRef.promote()); 14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (c != 0) { 14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian c->detachLayer(this); 14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 147921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 1486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 14996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 15096f0819f81293076e652792794a961543e6750d7Mathias Agopian 15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks 15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 155c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, 15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWComposer::HWCLayerInterface* layer) { 15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer) { 15813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer->onDisplayed(); 15913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); 16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 16213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 1636b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) { 1646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Add this buffer from our internal queue tracker 1656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza { // Autolock scope 1666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 1676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.push_back(item); 1686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 1703d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 17199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 172579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 173579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 1746b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) { 1756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 1766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (mQueueItems.empty()) { 1776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza ALOGE("Can't replace a frame on an empty queue"); 1786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return; 1796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.editItemAt(0) = item; 1816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza} 1826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 183399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() { 184399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { 185399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // mSidebandStreamChanged was false 186399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mFlinger->signalLayerUpdate(); 187399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 188399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall} 189399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 1906710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after 1916710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before 1926710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list) 19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() { 194bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->abandon(); 19548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 196cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up 19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const { 20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mName; 20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian PixelFormat format, uint32_t flags) 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t const maxSurfaceDims = min( 20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 21113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // never allow a surface larger than what our underlying GL implementation 21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // can handle. 21313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 21413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 21513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return BAD_VALUE; 21613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 21713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 21813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFormat = format; 21913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 22003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false; 22113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 22213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 22313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentOpacity = getOpacityForFormat(format); 22413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 22513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 22613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 22713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 22813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 22913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return NO_ERROR; 23013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 23113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() { 2334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Mutex::Autolock _l(mLock); 2344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian LOG_ALWAYS_FATAL_IF(mHasSurface, 2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian "Layer::getHandle() has already been called"); 2374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian mHasSurface = true; 2394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 240882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden /* 2414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * The layer handle is just a BBinder object passed to the client 2424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * (remote process) -- we don't keep any reference on our side such that 2434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * the dtor is called when the remote side let go of its reference. 244882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * 2454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for 2464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian * this layer when the handle is destroyed. 247882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden */ 2484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 2494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian class Handle : public BBinder, public LayerCleaner { 250a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 251a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 2524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) 2534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { 2544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian } 255a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return new Handle(mFlinger, this); 258582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 259582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 260b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const { 261b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza return mProducer; 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up 26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 268a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const { 269a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // this is the crop rectangle that applies to the buffer 270a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // itself (as opposed to the window) 271f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 272f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 273a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if the buffer crop is defined, we use that 274f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 275a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian } else if (mActiveBuffer != NULL) { 276a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // otherwise we use the whole buffer 277a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian crop = mActiveBuffer->getBounds(); 278f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 279a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian // if we don't have a buffer yet, we use an empty/invalid crop 2804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 281f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 282f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 283f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 284f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 285f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) { 286f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (CC_LIKELY(exclude.isEmpty())) { 287f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win; 288f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 289f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian if (exclude.isRect()) { 290f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return win.reduce(exclude.getBounds()); 291f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian } 292f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian return Region(win).subtract(exclude).getBounds(); 293f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian} 294f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 29513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const { 2961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 2976c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine return computeBounds(s.activeTransparentRegion); 2986c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine} 2996c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine 3006c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const { 3016c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine const Layer::State& s(getDrawingState()); 30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 3066c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 3076c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine return reduce(win, activeTransparentRegion); 30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3106b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { 31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the content crop is the area of the content that gets scaled to the 31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layer's size. 3136b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian FloatRect crop(getContentCrop()); 31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // the active.crop is the area of the window that gets cropped, but not 31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // scaled in any ways. 3171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the projection's clipping to the window crop in 32013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // layerstack space, and convert-back to layer space. 3216b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // if there are no window scaling involved, this operation will map to full 3226b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // pixels in the buffer. 3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // FIXME: the 3 lines below can produce slightly incorrect clipping when we have 3246b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // a viewport clipping and a window transform. we should use floating point to fix this. 3250e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian 3260e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian Rect activeCrop(s.active.w, s.active.h); 3270e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian if (!s.active.crop.isEmpty()) { 3280e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian activeCrop = s.active.crop; 3290e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian } 3300e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian 3310e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian activeCrop = s.transform.transform(activeCrop); 33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(hw->getViewport(), &activeCrop); 33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop = s.transform.inverse().transform(activeCrop); 33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 33528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // This needs to be here as transform.transform(Rect) computes the 33628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transformed rect and then takes the bounding box of the result before 33728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // returning. This means 33828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transform.inverse().transform(transform.transform(Rect)) != Rect 33928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // in which case we need to make sure the final rect is clipped to the 34028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // display bounds. 34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 34213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 343f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian // subtract the transparent region and snap to the bounds 344f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian activeCrop = reduce(activeCrop, s.activeTransparentRegion); 345f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian 34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!activeCrop.isEmpty()) { 34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Transform the window crop to match the buffer coordinate system, 34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // which means using the inverse of the current transform set on the 34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // SurfaceFlingerConsumer. 3506b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian uint32_t invTransform = mCurrentTransform; 351f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 352f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine /* 353f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine * the code below applies the display's inverse transform to the buffer 354f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine */ 355f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine uint32_t invTransformOrient = hw->getOrientationTransform(); 356f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine // calculate the inverse transform 357f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) { 358f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 359f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 3601440963470cda68be762957e2efb7ecbe1570366Michael Lentine // If the transform has been rotated the axis of flip has been swapped 3611440963470cda68be762957e2efb7ecbe1570366Michael Lentine // so we need to swap which flip operations we are performing 3621440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 3631440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 3641440963470cda68be762957e2efb7ecbe1570366Michael Lentine if (is_h_flipped != is_v_flipped) { 3651440963470cda68be762957e2efb7ecbe1570366Michael Lentine invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 3661440963470cda68be762957e2efb7ecbe1570366Michael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 3671440963470cda68be762957e2efb7ecbe1570366Michael Lentine } 368f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine } 369f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine // and apply to the current transform 370f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation(); 371f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine } 372f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine 37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winWidth = s.active.w; 37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian int winHeight = s.active.h; 37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 3767b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // If the activeCrop has been rotate the ends are rotated but not 3777b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // the space itself so when transforming ends back we can't rely on 3787b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // a modification of the axes of rotation. To account for this we 3797b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // need to reorient the inverse rotation in terms of the current 3807b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine // axes of rotation. 3817b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 3827b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 3837b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine if (is_h_flipped == is_v_flipped) { 3847b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 3857b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 3867b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine } 38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winWidth = s.active.h; 38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian winHeight = s.active.w; 38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect winCrop = activeCrop.transform( 391f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine invTransform, s.active.w, s.active.h); 39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 3936b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian // below, crop is intersected with winCrop expressed in crop's coordinate space 3946b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float xScale = crop.getWidth() / float(winWidth); 3956b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian float yScale = crop.getHeight() / float(winHeight); 39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 397f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetL = winCrop.left * xScale; 398f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetT = winCrop.top * yScale; 399f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetR = (winWidth - winCrop.right ) * xScale; 400f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine float insetB = (winHeight - winCrop.bottom) * yScale; 40113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 40213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.left += insetL; 40313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.top += insetT; 40413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.right -= insetR; 40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian crop.bottom -= insetB; 40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return crop; 40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 40913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 4104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 4114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<const DisplayDevice>& hw, 4124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 413a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 41413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setDefaultState(); 415a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 4163e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 4173e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 418a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 419dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (isSecure() && !hw->isSecure()) { 420dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis layer.setSkip(true); 421dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 422dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 42313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this gives us only the "orientation" component of the transform 4241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 4254125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (!isOpaque(s) || s.alpha != 0xFF) { 42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setBlending(mPremultipliedAlpha ? 42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_PREMULT : 42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian HWC_BLENDING_COVERAGE); 42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply the layer's transform, followed by the display's global transform 43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // here we're guaranteed that the layer's transform preserves rects 4336c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Region activeTransparentRegion(s.activeTransparentRegion); 4346c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine if (!s.active.crop.isEmpty()) { 4356c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Rect activeCrop(s.active.crop); 4366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop = s.transform.transform(activeCrop); 4376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop.intersect(hw->getViewport(), &activeCrop); 4386c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop = s.transform.inverse().transform(activeCrop); 43928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // This needs to be here as transform.transform(Rect) computes the 44028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transformed rect and then takes the bounding box of the result before 44128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // returning. This means 44228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // transform.inverse().transform(transform.transform(Rect)) != Rect 44328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // in which case we need to make sure the final rect is clipped to the 44428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine // display bounds. 44528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 4466c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine // mark regions outside the crop as transparent 4476c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top)); 4486c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, 4496c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine s.active.w, s.active.h)); 4506c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(0, activeCrop.top, 4516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeCrop.left, activeCrop.bottom)); 4526c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top, 4536c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine s.active.w, activeCrop.bottom)); 4546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine } 4556c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine Rect frame(s.transform.transform(computeBounds(activeTransparentRegion))); 45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian frame.intersect(hw->getViewport(), &frame); 45713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr(hw->getTransform()); 45813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setFrame(tr.transform(frame)); 45913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setCrop(computeCrop(hw)); 4609f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian layer.setPlaneAlpha(s.alpha); 4619f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian 46229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 46329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 46429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 46529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 46629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 46729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 46829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 46929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 47029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 471c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian Transform transform(tr * s.transform * bufferOrientation); 472c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 473c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 474c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian /* 475c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * the code below applies the display's inverse transform to the buffer 476c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian */ 477c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian uint32_t invTransform = hw->getOrientationTransform(); 4781440963470cda68be762957e2efb7ecbe1570366Michael Lentine uint32_t t_orientation = transform.getOrientation(); 479c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // calculate the inverse transform 480c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 481c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 482c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian NATIVE_WINDOW_TRANSFORM_FLIP_H; 4831440963470cda68be762957e2efb7ecbe1570366Michael Lentine // If the transform has been rotated the axis of flip has been swapped 4841440963470cda68be762957e2efb7ecbe1570366Michael Lentine // so we need to swap which flip operations we are performing 4851440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 4861440963470cda68be762957e2efb7ecbe1570366Michael Lentine bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 4871440963470cda68be762957e2efb7ecbe1570366Michael Lentine if (is_h_flipped != is_v_flipped) { 4881440963470cda68be762957e2efb7ecbe1570366Michael Lentine t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 4891440963470cda68be762957e2efb7ecbe1570366Michael Lentine NATIVE_WINDOW_TRANSFORM_FLIP_H; 4901440963470cda68be762957e2efb7ecbe1570366Michael Lentine } 491c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 492c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // and apply to the current transform 4931440963470cda68be762957e2efb7ecbe1570366Michael Lentine transform = Transform(t_orientation) * Transform(invTransform); 494c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 49529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 49629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t orientation = transform.getOrientation(); 49813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 49913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we can only handle simple transformation 5003e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 501a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setTransform(orientation); 503a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 504a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 505a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 5064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 507d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 50813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we have to set the visible region on every frame because 50913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we currently free it during onLayerDisplayed(), which is called 51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // after HWComposer::commit() -- every frame. 51113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Apply this display's projection's viewport to the visible region 51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // before giving it to the HWC HAL. 51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& tr = hw->getTransform(); 51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian layer.setVisibleRegionScreen(visible); 51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 517399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (mSidebandStream.get()) { 518399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall layer.setSidebandStream(mSidebandStream); 519399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } else { 520399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // NOTE: buffer can be NULL if the client never drew into this 521399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // layer yet, or if we ran out of memory 522399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall layer.setBuffer(mActiveBuffer); 523399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 524c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 525dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 526c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, 527d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 528c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 529d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 530d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // TODO: there is a possible optimization here: we only need to set the 531d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // acquire fence the first time a new buffer is acquired on EACH display. 532d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 53303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { 534bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 5351df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (fence->isValid()) { 536c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 537dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 538dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 539dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 540dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 541dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 542c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 543c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 544c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 54503414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition( 54603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<const DisplayDevice>& hw) 54703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 54803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // this gives us only the "orientation" component of the transform 54903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const State& s(getCurrentState()); 55003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 55103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // apply the layer's transform, followed by the display's global transform 55203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // here we're guaranteed that the layer's transform preserves rects 55303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect win(s.active.w, s.active.h); 55403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (!s.active.crop.isEmpty()) { 55503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews win.intersect(s.active.crop, &win); 55603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 55703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // subtract the transparent region and snap to the bounds 55803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect bounds = reduce(win, s.activeTransparentRegion); 55903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect frame(s.transform.transform(bounds)); 56003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews frame.intersect(hw->getViewport(), &frame); 56103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Transform& tr(hw->getTransform()); 56203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews return Rect(tr.transform(frame)); 56303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 56403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 56513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing... 56713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 570c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, clip, false); 57113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 57213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 573c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw, 574c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const { 575c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, Region(hw->bounds()), useIdentityTransform); 57613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 57713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 578c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const { 579c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza onDraw(hw, Region(hw->bounds()), false); 580c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza} 581c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza 582c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip, 583c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5861c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 587a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 589179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 590179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 591179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 592179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 593179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 594179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 595179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 596179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 597179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 598f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 599f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 600179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 601179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(drawingLayers[i]); 60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (layer.get() == static_cast<Layer const*>(this)) 604179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 6054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 606179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 607179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 608179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 609179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 6101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 611179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 61597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the current buffer to the GL texture, and wait for it to be 61697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // ready for us to draw into. 617bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 618bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 61997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 620dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 621dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 622dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 623dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 624dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 625dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 626875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 627875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 628dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (!blackOutLayer) { 629cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 630eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 631cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 632cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 633cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 634bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 635bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 636cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 637c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 638c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 639c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian /* 640c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * the code below applies the display's inverse transform to the texture transform 641c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian */ 642c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 643c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // create a 4x4 transform matrix from the display transform flags 644c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); 645c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); 646c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); 647c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 648c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian mat4 tr; 649c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian uint32_t transform = hw->getOrientationTransform(); 650c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) 651c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * rot90; 652c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) 653c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * flipH; 654c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) 655c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = tr * flipV; 656c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 657c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // calculate the inverse 658c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian tr = inverse(tr); 659c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 660c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian // and finally apply it to the original texture matrix 661c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr); 662c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix)); 663c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian } 664c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian 665cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 66649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 66749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setFiltering(useFiltering); 66849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian mTexture.setMatrix(textureMatrix); 66949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian 67049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian engine.setupLayerTexturing(mTexture); 671a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 672875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.setupLayerBlackedOut(); 673a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 674c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza drawWithOpenGL(hw, clip, useIdentityTransform); 675875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableTexturing(); 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 679c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, 680c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Region& /* clip */, float red, float green, float blue, 681c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza float alpha) const 68213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 68319733a32799f792125913e746e8644d16f8dc223Mathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 684c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza computeGeometry(hw, mMesh, false); 68519733a32799f792125913e746e8644d16f8dc223Mathias Agopian engine.setupFillWithColor(red, green, blue, alpha); 68619733a32799f792125913e746e8644d16f8dc223Mathias Agopian engine.drawMesh(mMesh); 68713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 68813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 68913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL( 69013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<const DisplayDevice>& hw, const Region& clip) const { 69113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian clearWithOpenGL(hw, clip, 0,0,0,0); 69213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 69313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 694c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw, 695c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Region& /* clip */, bool useIdentityTransform) const { 69613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t fbHeight = hw->getHeight(); 6971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const State& s(getDrawingState()); 69813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 699c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza computeGeometry(hw, mMesh, useIdentityTransform); 70013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 70113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian /* 70213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * NOTE: the way we compute the texture coordinates here produces 70313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * different results than when we take the HWC path -- in the later case 70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * the "source crop" is rounded to texel boundaries. 70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * This can produce significantly different results when the texture 70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * is scaled by a large amount. 70713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * 70813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * The GL code below is more logical (imho), and the difference with 70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * HWC is due to a limitation of the HWC API to integers -- a question 710c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian * is suspend is whether we should ignore this problem or revert to 71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * GL composition when a buffer scaling is applied (maybe with some 71213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * minimal value)? Or, we could make GL behave like HWC -- but this feel 71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian * like more of a hack. 71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian */ 71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Rect win(computeBounds()); 71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float left = float(win.left) / float(s.active.w); 7183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float top = float(win.top) / float(s.active.h); 7193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float right = float(win.right) / float(s.active.w); 7203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float bottom = float(win.bottom) / float(s.active.h); 72113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 722875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // TODO: we probably want to generate the texture coords with the mesh 723875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // here we assume that we only have 4 vertices 724ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); 725ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[0] = vec2(left, 1.0f - top); 726ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[1] = vec2(left, 1.0f - bottom); 727ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[2] = vec2(right, 1.0f - bottom); 728ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian texCoords[3] = vec2(right, 1.0f - top); 72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 730875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine& engine(mFlinger->getRenderEngine()); 7314125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); 7325cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian engine.drawMesh(mMesh); 733875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine.disableBlending(); 73413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 73513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 7361681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const { 7371681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk int producerStickyTransform = 0; 7381681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform); 7391681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk if (ret != OK) { 7401681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__, 7411681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk strerror(-ret), ret); 7421681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk return 0; 7431681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk } 7441681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk return static_cast<uint32_t>(producerStickyTransform); 7451681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk} 7461681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk 74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) { 74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFiltering = filtering; 74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 75113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const { 75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mFiltering; 75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 755ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 756ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 757ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 758ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 759ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 760ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 761ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 7625773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) { 763a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 764a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 765ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 7665773d3f5b2694c647e010246dff99acc70131289Mathias Agopian switch (format) { 7675773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_RGBA_8888: 7685773d3f5b2694c647e010246dff99acc70131289Mathias Agopian case HAL_PIXEL_FORMAT_BGRA_8888: 769c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall case HAL_PIXEL_FORMAT_sRGB_A_8888: 770dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return false; 7715773d3f5b2694c647e010246dff99acc70131289Mathias Agopian } 7725773d3f5b2694c647e010246dff99acc70131289Mathias Agopian // in all other case, we have no blending (also for unknown formats) 773dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian return true; 774ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 775ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state 77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 780c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh, 781c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform) const 78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 7831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 784c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Transform tr(useIdentityTransform ? 785c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza hw->getTransform() : hw->getTransform() * s.transform); 78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t hw_h = hw->getHeight(); 78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Rect win(s.active.w, s.active.h); 78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!s.active.crop.isEmpty()) { 78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian win.intersect(s.active.crop, &win); 79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 7916c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian // subtract the transparent region and snap to the bounds 792f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian win = reduce(win, s.activeTransparentRegion); 7933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 794ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 795ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[0] = tr.transform(win.left, win.top); 796ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[1] = tr.transform(win.left, win.bottom); 797ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[2] = tr.transform(win.right, win.bottom); 798ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian position[3] = tr.transform(win.right, win.top); 7993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian for (size_t i=0 ; i<4 ; i++) { 8005cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i].y = hw_h - position[i].y; 80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 80213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 803ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 8044125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const 805a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 806a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 807a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 808db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 809a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 810db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 811a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 812a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 813a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 8144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity; 815a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 816a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 8177a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 8187a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 819a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 8207a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 8217a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 8227a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 823b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const { 82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const { 82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !mCurrentCrop.isEmpty(); 83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return mNeedsFiltering || hw->needsFiltering(); 83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) { 83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleRegion = visibleRegion; 83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) { 84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->coveredRegion = coveredRegion; 84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region& 84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setVisibleNonTransparentRegion) { 84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always called from main thread 84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction 85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) { 8571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 8581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 8591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 8601eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& c(getCurrentState()); 861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool sizeChanged = (c.requested.w != s.requested.w) || 8631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != s.requested.h); 864a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 865a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 866cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 8679d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 8686905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 869419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 870419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 871419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 872419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 8731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian this, getName().string(), mCurrentTransform, mCurrentScalingMode, 8741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.w, c.active.h, 8751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.left, 8761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.top, 8771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.right, 8781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.bottom, 8791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getWidth(), 8801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.active.crop.getHeight(), 8811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h, 8821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.left, 8831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.top, 8841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.right, 8851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.bottom, 8861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getWidth(), 8871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.crop.getHeight(), 8881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.w, s.active.h, 8891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.left, 8901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.top, 8911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.right, 8921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.bottom, 8931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getWidth(), 8941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.active.crop.getHeight(), 8951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.w, s.requested.h, 8961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.left, 8971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.top, 8981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.right, 8991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.bottom, 9001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getWidth(), 9011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian s.requested.crop.getHeight()); 902a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 9032a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 9042a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 905bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferSize( 9061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian c.requested.w, c.requested.h); 907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 908cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 9090cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 9100cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const bool resizePending = (c.requested.w != c.active.w) || 9121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian (c.requested.h != c.active.h); 9130cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9140cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 91513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // don't let Layer::doTransaction update the drawing state 9160cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 9170cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 9180cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 9190cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 9200cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 9210cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 9220cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 9230cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 9240cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 9250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 9260cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 9270cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 92813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // always set active to requested, unless we're asked not to 92913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // this is used by Layer, which special cases resizes. 93013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (flags & eDontUpdateGeometryState) { 93113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } else { 9321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Layer::State& editCurrentState(getCurrentState()); 9331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian editCurrentState.active = c.requested; 93413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 93513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 9361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (s.active != c.active) { 93713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 93813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= Layer::eVisibleRegion; 93913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 94013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 9411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (c.sequence != s.sequence) { 94213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // invalidate and recompute the visible regions if needed 94313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian flags |= eVisibleRegion; 94413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian this->contentDirty = true; 94513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 94613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // we may use linear filtering, if the matrix scales us 9471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const uint8_t type = c.transform.getType(); 9481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian mNeedsFiltering = (!c.transform.preserveRects() || 94913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian (type >= Transform::SCALE)); 95013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 95113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 95213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // Commit the transaction 95313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian commitTransaction(); 95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return flags; 955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 95713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() { 95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mDrawingState = mCurrentState; 959a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 960a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) { 96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_and(~flags, &mTransactionFlags) & flags; 96313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 96413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 96513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) { 96613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return android_atomic_or(flags, &mTransactionFlags); 96713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 96813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 96913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) { 97013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 97113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 97313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set(x, y); 97413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 97513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 97613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) { 97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.z == z) 97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.z = z; 98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) { 98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.w = w; 98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.h = h; 99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) { 99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.alpha == alpha) 99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.alpha = alpha; 99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.transform.set( 100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) { 10092ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian mCurrentState.requestedTransparentRegion = transparent; 101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) { 101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.flags == newFlags) 101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.flags = newFlags; 101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 102013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) { 102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.requested.crop == crop) 102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 102513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.requested.crop = crop; 102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) { 103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mCurrentState.layerStack == layerStack) 103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return false; 103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.sequence++; 103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mCurrentState.layerStack = layerStack; 103613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian setTransactionFlags(eTransactionNeeded); 103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return true; 1038a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 1039a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10446b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const { 10456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 10466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza nsecs_t expectedPresent = 10476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); 10486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return mQueueItems.empty() ? 10496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza false : mQueueItems[0].mTimestamp < expectedPresent; 10506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza} 10516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 10524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 10534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 1054399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall return mQueuedFrames > 0 || mSidebandStreamChanged; 105599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 105699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1057d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() { 1058d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (mFrameLatencyNeeded) { 1059bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 106082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setDesiredPresentTime(desiredPresentTime); 106182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1062bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 1063789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (frameReadyFence->isValid()) { 106482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyFence(frameReadyFence); 106582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 106682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // There was no fence for this frame, so assume that it was ready 106782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // to be presented at the desired present time. 106882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyTime(desiredPresentTime); 106982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 107082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 1071d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const HWComposer& hwc = mFlinger->getHwComposer(); 107282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 1073789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis if (presentFence->isValid()) { 107482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentFence(presentFence); 107582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 107682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // The HWC doesn't support present fences, so use the refresh 107782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // timestamp instead. 107882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 107982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentTime(presentTime); 108082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 108182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 108282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.advanceFrame(); 1083d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyNeeded = false; 1084d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 1085d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian} 1086d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 1087da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const { 108813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Layer::State& s(mDrawingState); 108913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 1090afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim && (mActiveBuffer != NULL || mSidebandStream != NULL); 1091da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 1092da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 10934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10951c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 10961c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 1097399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { 1098399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall // mSidebandStreamChanged was true 1099399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); 11005bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall recomputeVisibleRegions = true; 11015bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall 11025bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall const State& s(getDrawingState()); 11035bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall return s.transform.transform(Region(Rect(s.active.w, s.active.h))); 1104399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall } 1105399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall 11064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 11073d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 110899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 110999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 111099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 111199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 111299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 111399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 11144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 11154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 111699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 111799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1118351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 11194125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const State& s(getDrawingState()); 11204125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool oldOpacity = isOpaque(s); 1121351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 1122db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 1123bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 11242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 11252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 11262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 11271681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bool stickyTransformSet; 11282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 11291681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bool& recomputeVisibleRegions, bool stickySet) 11302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 11311681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk recomputeVisibleRegions(recomputeVisibleRegions), 11321681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk stickyTransformSet(stickySet) { 11332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 11342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 1136db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian const IGraphicBufferConsumer::BufferItem& item) { 11372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 11382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 11392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 11402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 11422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 11432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 11452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 11462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 11472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 11482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 11492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 11512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 11522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 11542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 11552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 11562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 11572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 11582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 11592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 11602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 11612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 11632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 11642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 11652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 11662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 11672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 11682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 11692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 11712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 11722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 11732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 11756905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 11762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 11772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 11786905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden bufWidth, bufHeight, item.mTransform, item.mScalingMode, 11792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 11802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 11812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 11822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 11832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 11842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 11852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 11862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 11872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 11882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 11892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 11902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 11912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 11922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 11932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 11942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 11951681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk if (!isFixedSize && !stickyTransformSet) { 11962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 11972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 11984824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 11991681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}", 12001681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk bufWidth, bufHeight, front.active.w, front.active.h); 12012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 12022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12042ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 12052ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // if the transparent region has changed (this test is 12062ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // conservative, but that's fine, worst case we're doing 12072ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // a bit of extra work), we latch the new one and we 12082ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian // trigger a visible-region recompute. 12092ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian if (!front.activeTransparentRegion.isTriviallyEqual( 12102ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.requestedTransparentRegion)) { 12112ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian front.activeTransparentRegion = front.requestedTransparentRegion; 12126c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 12136c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // We also need to update the current state so that 12146c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // we don't end-up overwriting the drawing state with 12156c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // this stale current state during the next transaction 12166c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // 12176c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // NOTE: We don't need to hold the transaction lock here 12186c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // because State::active is only accessed from this thread. 12196c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian current.activeTransparentRegion = front.activeTransparentRegion; 12206c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian 12216c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian // recompute visible region 12222ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian recomputeVisibleRegions = true; 12232ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian } 12242ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 12252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 12262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 12272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 12282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 12291681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, 12301681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk getProducerStickyTransform() != 0); 12312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 123241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, 123341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden mFlinger->mPrimaryDispSync); 12341585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult == BufferQueue::PRESENT_LATER) { 12351585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Producer doesn't want buffer to be displayed yet. Signal a 12361585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // layer update so we check again at the next opportunity. 12371585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 12381585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden return outDirtyRegion; 12391585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 12401585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 12416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Remove this buffer from our internal queue tracker 12426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza { // Autolock scope 12436b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza Mutex::Autolock lock(mQueueItemLock); 12446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza mQueueItems.removeAt(0); 12456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 12466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 12471585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // Decrement the queued-frames count. Signal another event if we 12481585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden // have more frames pending. 12491585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (android_atomic_dec(&mQueuedFrames) > 1) { 12501585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden mFlinger->signalLayerUpdate(); 12511585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden } 12521585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden 12531585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden if (updateResult != NO_ERROR) { 1254a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 1255a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 12564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1257a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 1258d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 1259351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 1260bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1261e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 1262e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 12634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1264e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 1265da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 12664824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 1267702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 1268e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 12692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 12702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 1271ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 12722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 1273702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1274bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1275bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1276bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1277702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 1278702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 1279702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 1280702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 1281702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 1282702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 1283702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 1284ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1285702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1286702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1287702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 1288e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 1289e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 1290702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 1291702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 1292ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 1293702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1294702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1295702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 1296702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 12974125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if (oldOpacity != isOpaque(s)) { 1298702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 1299702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 1300702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 13014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 13021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian Region dirtyRegion(Rect(s.active.w, s.active.h)); 13031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 13044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 13051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian outDirtyRegion = (s.transform.transform(dirtyRegion)); 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 13074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 131013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 131113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{ 131213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // TODO: should we do something special if mSecure is set? 131313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (mProtectedByApp) { 131413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // need a hardware-protected path to external video sink 131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 131613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 131703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (mPotentialCursor) { 131803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews usage |= GraphicBuffer::USAGE_CURSOR; 131903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 132013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian usage |= GraphicBuffer::USAGE_HW_COMPOSER; 132113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian return usage; 132213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 132313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 132413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 132513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian uint32_t orientation = 0; 132613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 132713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // The transform hint is used to improve performance, but we can 132813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // only have a single transform hint, it cannot 132913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // apply to all displays. 133013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Transform& planeTransform(hw->getTransform()); 133113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = planeTransform.getOrientation(); 133213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian if (orientation & Transform::ROT_INVALID) { 133313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian orientation = 0; 133413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 133513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian } 133613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mSurfaceFlingerConsumer->setTransformHint(orientation); 133713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian} 133813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 133913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 134013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging 134113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------- 134213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 13433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const 13441b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 13451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(getDrawingState()); 134613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 13473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.colorize(result, Colorizer::GREEN); 134874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 134913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "+ %s %p (%s)\n", 135013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian getTypeId(), this, getName().string()); 13513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 135213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 13532ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian s.activeTransparentRegion.dump(result, "transparentRegion"); 135413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian visibleRegion.dump(result, "visibleRegion"); 135513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Client> client(mClientRef.promote()); 135613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 135774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( " " 135813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 135913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "isOpaque=%1d, invalidate=%1d, " 136013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 136113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian " client=%p\n", 136213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 136313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.left, s.active.crop.top, 136413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.active.crop.right, s.active.crop.bottom, 13654125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden isOpaque(s), contentDirty, 136613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.alpha, s.flags, 136713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[0][0], s.transform[0][1], 136813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian s.transform[1][0], s.transform[1][1], 136913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian client.get()); 13701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1371a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 1372a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 13731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 13741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 13751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 13761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 1377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 13781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 137974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 13801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 1381ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 13826905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden " queued-frames=%d, mRefreshPending=%d\n", 1383a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 13846905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mQueuedFrames, mRefreshPending); 13851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 1386bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mSurfaceFlingerConsumer != 0) { 138774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mSurfaceFlingerConsumer->dump(result, " "); 1388bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 1389d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 1390d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 1391d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const { 1392d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.dumpStats(result); 139382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 139482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 1395d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() { 1396d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.clearStats(); 139725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 139825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 13996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() { 14006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mFrameTracker.logAndResetStats(mName); 14016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 14026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 1403d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const { 1404d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mFrameTracker.getStats(outStats); 1405d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 1406d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 140713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// --------------------------------------------------------------------------- 140813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian 140913127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 141013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer) 141113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : mFlinger(flinger), mLayer(layer) { 1412b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 1413b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 141413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() { 141513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian // destroy client resources 141613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian mFlinger->onLayerDestroyed(mLayer); 1417a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 1418a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 1419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 14203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android 1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 14233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 14243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 14273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 14283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 1429