Layer.cpp revision 1df8c345854155cbbcb9f80de9d12d66ea70ac08
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> 2290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <math.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h> 25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h> 26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 390f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h" 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 43a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h" 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h" 461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 533ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) 543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : LayerBaseClient(flinger, client), 55a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mTextureName(-1U), 56a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mQueuedFrames(0), 57a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentTransform(0), 58933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity(true), 604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending(false), 6182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyNeeded(false), 625bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mFormat(PIXEL_FORMAT_NONE), 631f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer(true), 65b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 66933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mProtectedByApp(false) 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glGenTextures(1, &mTextureName); 70e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 71e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 73d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface* layer) { 74c39736088398a9b4367b30fc307ed7de96ac342eMathias Agopian LayerBaseClient::onLayerDisplayed(hw, layer); 75ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (layer) { 76bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); 77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 78d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 80a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef() 8196f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LayerBaseClient::onFirstRef(); 83ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian 84bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 85b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam sp<BufferQueue> bq = new SurfaceTextureLayer(); 86bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, 87a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian GL_TEXTURE_EXTERNAL_OES, false, bq); 88b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 89bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 90bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFrameAvailableListener(this); 91bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setSynchronousMode(true); 92b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 937f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 947f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 95bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 967f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 97bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 98303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 996905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 1008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 1018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian updateTransformHint(hw); 102b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 10396f0819f81293076e652792794a961543e6750d7Mathias Agopian 104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer() 105b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 106921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 10796f0819f81293076e652792794a961543e6750d7Mathias Agopian} 10896f0819f81293076e652792794a961543e6750d7Mathias Agopian 109a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() { 1103d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 11199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 114d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 115d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 116d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 117d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 118bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->abandon(); 11948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 120cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 121a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) { 122a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis LayerBase::setName(name); 123bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setName(name); 124a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis} 125a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis 126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface() 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 128882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden /* 129882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * This class provides an implementation of BnSurface (the "native" or 130882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * "remote" side of the Binder IPC interface ISurface), and mixes in 131882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for 132882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * this layer when the BSurface is destroyed. 133882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * 134882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * The idea is to provide a handle to the Layer through ISurface that 135882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * is cleaned up automatically when the last reference to the ISurface 136882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * goes away. (The references will be held on the "proxy" side, while 137882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * the Layer exists on the "native" side.) 138882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * 139882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * The Layer has a reference to an instance of SurfaceFlinger's variant 140882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * of GLConsumer, which holds a reference to the BufferQueue. The 141882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * getSurfaceTexture() call returns a Binder interface reference for 142882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden * the producer interface of the buffer queue associated with the Layer. 143882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden */ 144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class BSurface : public BnSurface, public LayerCleaner { 145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 1462adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { 1472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden sp<IGraphicBufferProducer> res; 148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const Layer> that( mOwner.promote() ); 149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != NULL) { 150bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden res = that->mSurfaceFlingerConsumer->getBufferQueue(); 151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return res; 153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 154a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian BSurface(const sp<SurfaceFlinger>& flinger, 156a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<Layer>& layer) 157a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { } 158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> sur(new BSurface(mFlinger, this)); 160a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const 164582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{ 165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return mSurfaceFlingerConsumer->getBufferQueue()->asBinder(); 166582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 167582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 168f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 171401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 174ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian if (err) { 175ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("unsupported pixelformat %d", format); 176ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian return err; 177ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian } 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 180a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 181ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 182ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 183ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 184ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 185ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 186ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 187ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 188ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 189cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 1913165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 1923165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 1933165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 194a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity = getOpacityForFormat(format); 195a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 196bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 197bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 199ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 203f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const { 204bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Start with the SurfaceFlingerConsumer's buffer crop... 205f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 206f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 207f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 208f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else if (mActiveBuffer != NULL){ 209f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 210f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 2114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 2124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return crop; 213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 214f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 215f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // ... then reduce that in the same proportions as the window crop reduces 216f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // the window size. 217f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis const State& s(drawingState()); 21893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian if (!s.active.crop.isEmpty()) { 219f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Transform the window crop to match the buffer coordinate system, 220f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // which means using the inverse of the current transform set on the 221bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // SurfaceFlingerConsumer. 222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis uint32_t invTransform = mCurrentTransform; 22393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winWidth = s.active.w; 22493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winHeight = s.active.h; 225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis NATIVE_WINDOW_TRANSFORM_FLIP_H; 22893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winWidth = s.active.h; 22993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winHeight = s.active.w; 230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 23193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian Rect winCrop = s.active.crop.transform(invTransform, 23293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian s.active.w, s.active.h); 233f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float xScale = float(crop.width()) / float(winWidth); 235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float yScale = float(crop.height()) / float(winHeight); 23693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.left += int(ceilf(float(winCrop.left) * xScale)); 23793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.top += int(ceilf(float(winCrop.top) * yScale)); 23893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 23993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 240f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 244f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 2454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 2464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<const DisplayDevice>& hw, 2474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 2494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian LayerBaseClient::setGeometry(hw, layer); 250a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 2513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 2523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 253a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 254dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (isSecure() && !hw->isSecure()) { 255dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis layer.setSkip(true); 256dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 257dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 2589f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian const State& s(drawingState()); 2599f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian layer.setPlaneAlpha(s.alpha); 2609f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian 26129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 26229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 26329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 26429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 26529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 26629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 26729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 26829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 26929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 2704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Transform tr(hw->getTransform() * s.transform * bufferOrientation); 27129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 27229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 27329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const uint32_t finalTransform = tr.getOrientation(); 27429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 275a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can only handle simple transformation 27629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian if (finalTransform & Transform::ROT_INVALID) { 2773e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 278a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 2793e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setTransform(finalTransform); 280a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 2813e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setCrop(computeBufferCrop()); 282a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 283a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 285d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 28671e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian LayerBaseClient::setPerFrameData(hw, layer); 2873e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 2883e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // layer yet, or if we ran out of memory 28971e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian layer.setBuffer(mActiveBuffer); 290c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 291dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 2924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 293d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 294c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 295d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 296d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // TODO: there is a possible optimization here: we only need to set the 297d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // acquire fence the first time a new buffer is acquired on EACH display. 298d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 299d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (layer.getCompositionType() == HWC_OVERLAY) { 300bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 3011df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (fence->isValid()) { 302c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 303dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 304dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 305dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 306dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 307dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 308c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 309c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 310c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 3114297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 3141c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 315a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 319179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 326f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 327f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 3334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 3381b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 342a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 34397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the current buffer to the GL texture, and wait for it to be 34497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // ready for us to draw into. 345bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 346bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 34797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 348dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 349dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 350dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 351dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 352dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 353dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 354dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (!blackOutLayer) { 355cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 356eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 357cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 358cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 359cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 360bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 361bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 362cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 363cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 364c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 365c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian GLenum filter = GL_NEAREST; 366cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis if (useFiltering) { 367c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian filter = GL_LINEAR; 3689575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis } 369c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 370c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 3719575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 372cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis glLoadMatrixf(textureMatrix); 3739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 374c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 3754c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet glEnable(GL_TEXTURE_EXTERNAL_OES); 376a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 377c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 3789575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 3799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glLoadIdentity(); 3809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 381c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 382c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glEnable(GL_TEXTURE_2D); 383a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 384a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 3851b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian drawWithOpenGL(hw, clip); 386a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 387c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 388c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 391ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 392ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 393ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 394ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 395ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 396ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 397ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 398a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) 399ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 402ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 403a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormatInfo info; 404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = getPixelFormatInfo(PixelFormat(format), &info); 405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // in case of error (unknown format), we assume no blending 406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return (err || info.h_alpha <= info.l_alpha); 407ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 408ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 409ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 410a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const 411a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 412a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 413a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 414db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 415a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 416db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 417a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 420a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mOpaqueLayer || mCurrentOpacity; 421a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 422a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 4237a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 4247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 425a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 4267a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 4277a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4287a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 429b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4374824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian const bool sizeChanged = (temp.requested.w != front.requested.w) || 4384824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian (temp.requested.h != front.requested.h); 439a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 440a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 441cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 4429d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 4436905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 444419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 4486905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode, 449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.w, temp.active.h, 450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.left, 451419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.top, 452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.right, 453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.bottom, 454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getWidth(), 455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getHeight(), 456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.requested.w, temp.requested.h, 457b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.left, 458b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.top, 459b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.right, 460b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.bottom, 461b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getWidth(), 462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getHeight(), 463419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.w, front.active.h, 464419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.left, 465419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.top, 466419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.right, 467419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.bottom, 468419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getWidth(), 469419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getHeight(), 470419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.w, front.requested.h, 471b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.left, 472b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.top, 473b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.right, 474b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.bottom, 475b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.getWidth(), 476419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.crop.getHeight()); 477a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 4782a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 4792a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 480bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setDefaultBufferSize( 481b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.w, temp.requested.h); 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 483cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 4840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 4850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian const bool resizePending = (temp.requested.w != temp.active.w) || 4870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian (temp.requested.h != temp.active.h); 4880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // don't let LayerBase::doTransaction update the drawing state 4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 4930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 4940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 4950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 4960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 4970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 4980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 5000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 5010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 5020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 506a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const { 507933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 508a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const { 511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return !mCurrentCrop.isEmpty(); 512a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 513a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5184d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 5194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 5204d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return mQueuedFrames > 0; 52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 523d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() { 524d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (mFrameLatencyNeeded) { 525bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 52682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setDesiredPresentTime(desiredPresentTime); 52782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 528bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 52982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (frameReadyFence != NULL) { 53082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyFence(frameReadyFence); 53182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 53282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // There was no fence for this frame, so assume that it was ready 53382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // to be presented at the desired present time. 53482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setFrameReadyTime(desiredPresentTime); 53582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 53682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 537d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const HWComposer& hwc = mFlinger->getHwComposer(); 53882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 53982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (presentFence != NULL) { 54082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentFence(presentFence); 54182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } else { 54282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // The HWC doesn't support present fences, so use the refresh 54382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // timestamp instead. 54482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 54582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.setActualPresentTime(presentTime); 54682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 54782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 54882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.advanceFrame(); 549d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyNeeded = false; 550d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 551d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian} 552d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 553da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const { 554da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); 555da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 556da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 5574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5591c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 5623d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 56399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 56499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 56599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 56699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 56799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 56899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 5694d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 57199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 57299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 573351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 574db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis const bool oldOpacity = isOpaque(); 575351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 576db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 5773d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // signal another event if we have more frames pending 5783d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (android_atomic_dec(&mQueuedFrames) > 1) { 57999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 5803d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis } 5813d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 582bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions) 5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions(recomputeVisibleRegions) { 5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const BufferQueue::BufferItem& item) { 5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 6336905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 6352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 6366905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden bufWidth, bufHeight, item.mTransform, item.mScalingMode, 6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 6392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 6402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 6412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 6422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 6432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 6442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 6452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 6462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 6472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 6482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 6492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 6502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 6512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (!isFixedSize) { 6542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 6552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 6564824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 6612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 6632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 6662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 667bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) { 668a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 669a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 671a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 672d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 673351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 674bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 675e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 676e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 678e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 679da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6804824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 682e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 6832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 6842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 685ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 6862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 688bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 689bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 690bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 691702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 692702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 693702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 694702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 695702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 696702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 697702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 698ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 699702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 700702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 701702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 702e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 703e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 704702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 705702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 706ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden recomputeVisibleRegions = true; 707702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 708702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 709702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 710702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 711702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldOpacity != isOpaque()) { 712702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 713702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 714702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 715702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 716702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 7194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Layer::State& front(drawingState()); 7204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion(Rect(front.active.w, front.active.h)); 7211c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 7224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 7234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian outDirtyRegion = (front.transform.transform(dirtyRegion)); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 7291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 7301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 732a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 733a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 7341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7371b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 738a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 7391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 742ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 7436905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden " queued-frames=%d, mRefreshPending=%d\n", 744a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 7456905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mQueuedFrames, mRefreshPending); 7461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 748d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 749bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mSurfaceFlingerConsumer != 0) { 750bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE); 751bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 752d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 753d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 75482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 75582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 75682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian LayerBaseClient::dumpStats(result, buffer, SIZE); 75782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.dump(result); 75882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 75982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 76025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats() 76125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 76225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian LayerBaseClient::clearStats(); 76382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis mFrameTracker.clear(); 76425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 76525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 766a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 767b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 768a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: should we do something special if mSecure is set? 769a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mProtectedByApp) { 770a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // need a hardware-protected path to external video sink 771a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 772b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 7733599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis usage |= GraphicBuffer::USAGE_HW_COMPOSER; 774a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return usage; 775b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 776b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 7778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian uint32_t orientation = 0; 779a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 7808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint is used to improve performance, but we can 7818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // only have a single transform hint, it cannot 7824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // apply to all displays. 7834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Transform& planeTransform(hw->getTransform()); 7844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian orientation = planeTransform.getOrientation(); 785a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (orientation & Transform::ROT_INVALID) { 786a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian orientation = 0; 787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 788a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 789bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mSurfaceFlingerConsumer->setTransformHint(orientation); 790a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 791a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 796