Layer.cpp revision da27af9832a0170f1fc40ef3f21371c4d30d21b3
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), 6282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyOffset(0), 635bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mFormat(PIXEL_FORMAT_NONE), 641f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 65a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer(true), 66b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 67933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mProtectedByApp(false) 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glGenTextures(1, &mTextureName); 71e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 72e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 74d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface* layer) { 75c39736088398a9b4367b30fc307ed7de96ac342eMathias Agopian LayerBaseClient::onLayerDisplayed(hw, layer); 76ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (layer) { 77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd()); 78ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 80d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef() 8296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 83a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LayerBaseClient::onFirstRef(); 84ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian 85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 86a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian FrameQueuedListener(Layer* layer) : mLayer(layer) { } 87a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian private: 88a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<Layer> mLayer; 89a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual void onFrameAvailable() { 90a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<Layer> that(mLayer.promote()); 91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != 0) { 92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian that->onFrameQueued(); 93a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 94a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 95a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 96b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 97b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // Creates a custom BufferQueue for SurfaceTexture to use 98b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam sp<BufferQueue> bq = new SurfaceTextureLayer(); 99b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture = new SurfaceTexture(mTextureName, true, 100a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian GL_TEXTURE_EXTERNAL_OES, false, bq); 101b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 102b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setSynchronousMode(true); 105b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1067f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1077f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 10831a353da225af5329735451c761b430d82dfda1bJamie Gennis mSurfaceTexture->setDefaultMaxBufferCount(2); 1097f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 11031a353da225af5329735451c761b430d82dfda1bJamie Gennis mSurfaceTexture->setDefaultMaxBufferCount(3); 111303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 1126905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden 1136905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden updateTransformHint(); 114b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 11596f0819f81293076e652792794a961543e6750d7Mathias Agopian 116a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer() 117b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 118921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 11996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 12096f0819f81293076e652792794a961543e6750d7Mathias Agopian 121a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() { 1223d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 124579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 125579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 126d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 127d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 128d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 129d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 130dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis mSurfaceTexture->abandon(); 13148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 132cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 133a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) { 134a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis LayerBase::setName(name); 135a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis mSurfaceTexture->setName(name); 136a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis} 137a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis 138a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface() 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 140a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class BSurface : public BnSurface, public LayerCleaner { 141a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 142a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual sp<ISurfaceTexture> getSurfaceTexture() const { 143a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurfaceTexture> res; 144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const Layer> that( mOwner.promote() ); 145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != NULL) { 146b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam res = that->mSurfaceTexture->getBufferQueue(); 147a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return res; 149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 150a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian BSurface(const sp<SurfaceFlinger>& flinger, 152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<Layer>& layer) 153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { } 154a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> sur(new BSurface(mFlinger, this)); 156a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const 160582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{ 161b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mSurfaceTexture->getBufferQueue()->asBinder(); 162582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 163582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 164f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 167401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 170ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian if (err) { 171ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("unsupported pixelformat %d", format); 172ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian return err; 173ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian } 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 176a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 178ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 181ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 182ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 183ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 184ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 185cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 186eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 1873165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 1883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 1893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 190a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity = getOpacityForFormat(format); 191a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 192a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferSize(w, h); 193a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferFormat(format); 194b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 195ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 199f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const { 200f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Start with the SurfaceTexture's buffer crop... 201f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 202f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 203f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 204f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else if (mActiveBuffer != NULL){ 205f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 206f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 2074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 2084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return crop; 209f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 210f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 211f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // ... then reduce that in the same proportions as the window crop reduces 212f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // the window size. 213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis const State& s(drawingState()); 21493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian if (!s.active.crop.isEmpty()) { 215f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Transform the window crop to match the buffer coordinate system, 216f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // which means using the inverse of the current transform set on the 217f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // SurfaceTexture. 218f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis uint32_t invTransform = mCurrentTransform; 21993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winWidth = s.active.w; 22093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winHeight = s.active.h; 221f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis NATIVE_WINDOW_TRANSFORM_FLIP_H; 22493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winWidth = s.active.h; 22593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winHeight = s.active.w; 226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 22793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian Rect winCrop = s.active.crop.transform(invTransform, 22893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian s.active.w, s.active.h); 229f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float xScale = float(crop.width()) / float(winWidth); 231f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float yScale = float(crop.height()) / float(winHeight); 23293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.left += int(ceilf(float(winCrop.left) * xScale)); 23393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.top += int(ceilf(float(winCrop.top) * yScale)); 23493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 23593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 237f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 238f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 239f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 240f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 2414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 2424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<const DisplayDevice>& hw, 2434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 244a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 2454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian LayerBaseClient::setGeometry(hw, layer); 246a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 2473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 2483e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 249a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 250a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can't do alpha-fade with the hwc HAL 251a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const State& s(drawingState()); 252a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (s.alpha < 0xFF) { 2533e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 254a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 255a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 25629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 25729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 25829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 25929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 26029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 26129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 26229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 26329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 26429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 2654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Transform tr(hw->getTransform() * s.transform * bufferOrientation); 26629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 26729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 26829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const uint32_t finalTransform = tr.getOrientation(); 26929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 270a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can only handle simple transformation 27129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian if (finalTransform & Transform::ROT_INVALID) { 2723e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 273a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 2743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setTransform(finalTransform); 275a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 2763e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setCrop(computeBufferCrop()); 277a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 278a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 280d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 28171e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian LayerBaseClient::setPerFrameData(hw, layer); 2823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 2833e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // layer yet, or if we ran out of memory 28471e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian layer.setBuffer(mActiveBuffer); 285c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 286dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 2874297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 288d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian HWComposer::HWCLayerInterface& layer) { 289c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 290d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 291d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // TODO: there is a possible optimization here: we only need to set the 292d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian // acquire fence the first time a new buffer is acquired on EACH display. 293d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 294d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (layer.getCompositionType() == HWC_OVERLAY) { 295dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall sp<Fence> fence = mSurfaceTexture->getCurrentFence(); 296dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fence.get()) { 297c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 298dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 299dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 300dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 301dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 302dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 303c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 304c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 305c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 3064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 3091c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 310a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 312179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 313179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 314179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 315179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 316179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 319179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 321f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 322f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 3284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 3331b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 337a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 33861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis status_t err = mSurfaceTexture->doGLFenceWait(); 33961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != OK) { 34061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ALOGE("onDraw: failed waiting for fence: %d", err); 341dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 342dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 343dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 344dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 3459575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis if (!isProtected()) { 346cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 347cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 348cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 349cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 350cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 351cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->setFilteringEnabled(useFiltering); 352cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->getTransformMatrix(textureMatrix); 353cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 354cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 355c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 356c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian GLenum filter = GL_NEAREST; 357cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis if (useFiltering) { 358c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian filter = GL_LINEAR; 3599575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis } 360c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 361c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 3629575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 363cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis glLoadMatrixf(textureMatrix); 3649575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 365c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 3664c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet glEnable(GL_TEXTURE_EXTERNAL_OES); 367a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 368c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 3699575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 3709575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glLoadIdentity(); 3719575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 372c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 373c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glEnable(GL_TEXTURE_2D); 374a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 375a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 3761b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian drawWithOpenGL(hw, clip); 377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 378c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 379c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 382ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 383ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 384ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 385ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 386ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 387ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 388ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 389a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) 390ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 391a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 392a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 393ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormatInfo info; 395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = getPixelFormatInfo(PixelFormat(format), &info); 396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // in case of error (unknown format), we assume no blending 397a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return (err || info.h_alpha <= info.l_alpha); 398ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 399ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 400ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const 402a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 403a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 405db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 407db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 408a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 410a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 411a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mOpaqueLayer || mCurrentOpacity; 412a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 413a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 4147a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 4157a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 416a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 4177a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 4187a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4197a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 420b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4241c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4284824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian const bool sizeChanged = (temp.requested.w != front.requested.w) || 4294824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian (temp.requested.h != front.requested.h); 430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 431a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 432cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 4339d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 4346905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 435419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 436419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 437419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 438419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 4396905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode, 440419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.w, temp.active.h, 441419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.left, 442419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.top, 443419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.right, 444419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.bottom, 445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getWidth(), 446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getHeight(), 447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.requested.w, temp.requested.h, 448b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.left, 449b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.top, 450b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.right, 451b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.bottom, 452b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getWidth(), 453b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getHeight(), 454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.w, front.active.h, 455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.left, 456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.top, 457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.right, 458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.bottom, 459419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getWidth(), 460419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getHeight(), 461419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.w, front.requested.h, 462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.left, 463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.top, 464b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.right, 465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.bottom, 466b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.getWidth(), 467419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.crop.getHeight()); 468a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 4692a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 4702a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 471b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian mSurfaceTexture->setDefaultBufferSize( 472b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.w, temp.requested.h); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 474cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 4750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 4760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian const bool resizePending = (temp.requested.w != temp.active.w) || 4780cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian (temp.requested.h != temp.active.h); 4790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 4810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // don't let LayerBase::doTransaction update the drawing state 4820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 4830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 4840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 4850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 4860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 4870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 4880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 4890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 4930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 497a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const { 498933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 499a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 500a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 501a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const { 502a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return !mCurrentCrop.isEmpty(); 503a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 504a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 5104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 5114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return mQueuedFrames > 0; 51299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 51399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 514d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() { 515d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian if (mFrameLatencyNeeded) { 516d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const HWComposer& hwc = mFlinger->getHwComposer(); 517d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian const size_t offset = mFrameLatencyOffset; 518d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp(); 519d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameStats[offset].set = systemTime(); 520b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 521d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 522d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian mFrameLatencyNeeded = false; 523d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 524d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian} 525d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 526da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const { 527da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); 528da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian} 529da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 5304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 5353d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 5424d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 5434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 54599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 546351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 547db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis const bool oldOpacity = isOpaque(); 548351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 549db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 5503d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // signal another event if we have more frames pending 5513d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (android_atomic_dec(&mQueuedFrames) > 1) { 55299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 5533d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis } 5543d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 5552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian struct Reject : public SurfaceTexture::BufferRejecter { 5562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 5572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 5582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 5592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 5602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions) 5612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 5622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions(recomputeVisibleRegions) { 5632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const BufferQueue::BufferItem& item) { 5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 6066905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 6096905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden bufWidth, bufHeight, item.mTransform, item.mScalingMode, 6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (!isFixedSize) { 6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 6294824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 6362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 6392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 6434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 644a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 645d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 646351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 647351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 648e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 649e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 651e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 652da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6534824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 654702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 655e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 6562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian mFlinger->invalidateHwcGeometry(); 6592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 660702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 661702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian Rect crop(mSurfaceTexture->getCurrentCrop()); 6622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 6632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 664702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 666702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 667702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 668702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 669702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 670702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 671702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 672702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 673702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 674702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 675e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 676e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 677702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 678702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 679702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 680702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 682702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 683702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 684702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldOpacity != isOpaque()) { 685702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 686702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 688702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 689702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Layer::State& front(drawingState()); 6934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion(Rect(front.active.w, front.active.h)); 6941c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 6964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian outDirtyRegion = (front.transform.transform(dirtyRegion)); 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 7021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 7031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 705a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 706a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 7071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 711a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 7121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 715ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 7166905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden " queued-frames=%d, mRefreshPending=%d\n", 717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 7186905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mQueuedFrames, mRefreshPending); 7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 721d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mSurfaceTexture != 0) { 723a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->dump(result, " ", buffer, SIZE); 724bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 725d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 726d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 72782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 72882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 72982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian LayerBaseClient::dumpStats(result, buffer, SIZE); 73082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t o = mFrameLatencyOffset; 731b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden const nsecs_t period = 732b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 73382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\n", period); 73482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<128 ; i++) { 73582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t index = (o+i) % 128; 73682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_app = mFrameStats[index].timestamp; 73782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_set = mFrameStats[index].set; 73882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_vsync = mFrameStats[index].vsync; 73982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\t%lld\t%lld\n", 74082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_app, 74182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_vsync, 74282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_set); 74382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 74482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append("\n"); 74582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 74682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 74725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats() 74825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 74925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian LayerBaseClient::clearStats(); 75025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian memset(mFrameStats, 0, sizeof(mFrameStats)); 75125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 75225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 754b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 755a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: should we do something special if mSecure is set? 756a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mProtectedByApp) { 757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // need a hardware-protected path to external video sink 758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 759b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 7603599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis usage |= GraphicBuffer::USAGE_HW_COMPOSER; 761a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return usage; 762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 763b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 7646905205c8d130b6ea3a813c1b9283492ed183367Andy McFaddenvoid Layer::updateTransformHint() const { 765a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian uint32_t orientation = 0; 766a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 7674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // The transform hint is used to improve performance on the main 7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // display -- we can only have a single transform hint, it cannot 7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // apply to all displays. 7704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // This is why we use the default display here. This is not an 7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // oversight. 7724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 7734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const Transform& planeTransform(hw->getTransform()); 7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian orientation = planeTransform.getOrientation(); 775a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (orientation & Transform::ROT_INVALID) { 776a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian orientation = 0; 777a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 7796905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden mSurfaceTexture->setTransformHint(orientation); 780a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 781a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 786