Layer.cpp revision 1b03149f3533db04e72e088d3fdd09d0087ca594
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" 391b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.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 5396f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, 5496f0819f81293076e652792794a961543e6750d7Mathias Agopian DisplayID display, const sp<Client>& client) 5596f0819f81293076e652792794a961543e6750d7Mathias Agopian : LayerBaseClient(flinger, display, client), 56a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mTextureName(-1U), 57a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mQueuedFrames(0), 58a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentTransform(0), 59933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 60a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity(true), 614d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending(false), 6282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyNeeded(false), 6382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyOffset(0), 645bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mFormat(PIXEL_FORMAT_NONE), 651f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer(true), 67b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 68933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mProtectedByApp(false) 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glGenTextures(1, &mTextureName); 72e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 73e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 74ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallvoid Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) { 75ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (layer) { 76ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd()); 77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 78ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 79e8696a40e09b24b634214684d18526187b316a2fJamie Gennis if (mFrameLatencyNeeded) { 801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // we need a DisplayHardware for debugging only right now 811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // XXX: should this be called per DisplayHardware? 821b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 8382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); 8482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].set = systemTime(); 8582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); 86e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 87e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mFrameLatencyNeeded = false; 88e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 89d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef() 9296f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 93a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LayerBaseClient::onFirstRef(); 94ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian 95a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 96a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian FrameQueuedListener(Layer* layer) : mLayer(layer) { } 97a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian private: 98a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<Layer> mLayer; 99a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual void onFrameAvailable() { 100a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<Layer> that(mLayer.promote()); 101a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != 0) { 102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian that->onFrameQueued(); 103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 105a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 106b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 107b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // Creates a custom BufferQueue for SurfaceTexture to use 108b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam sp<BufferQueue> bq = new SurfaceTextureLayer(); 109b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture = new SurfaceTexture(mTextureName, true, 110a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian GL_TEXTURE_EXTERNAL_OES, false, bq); 111b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 112b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 114a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setSynchronousMode(true); 115b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1167f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1177f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 118a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setBufferCountServer(2); 1197f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 1207f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian mSurfaceTexture->setBufferCountServer(3); 121303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 122b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 12396f0819f81293076e652792794a961543e6750d7Mathias Agopian 124a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer() 125b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 126118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mFlinger->postMessageAsync( 127118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); 12896f0819f81293076e652792794a961543e6750d7Mathias Agopian} 12996f0819f81293076e652792794a961543e6750d7Mathias Agopian 130a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() { 1313d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 13299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 133579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 134579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 135d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 136d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 137d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 138d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 139dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis mSurfaceTexture->abandon(); 14048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 141cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 142a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) { 143a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis LayerBase::setName(name); 144a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis mSurfaceTexture->setName(name); 145a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis} 146a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis 1471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid Layer::validateVisibility(const Transform& globalTransform, const DisplayHardware& hw) { 1481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian LayerBase::validateVisibility(globalTransform, hw); 149b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 150b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // This optimization allows the SurfaceTexture to bake in 151b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // the rotation so hardware overlays can be used 152b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setTransformHint(getTransformHint()); 153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 154b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface() 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 157a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class BSurface : public BnSurface, public LayerCleaner { 158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual sp<ISurfaceTexture> getSurfaceTexture() const { 160a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurfaceTexture> res; 161a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const Layer> that( mOwner.promote() ); 162a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != NULL) { 163b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam res = that->mSurfaceTexture->getBufferQueue(); 164a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 165a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return res; 166a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 167a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 168a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian BSurface(const sp<SurfaceFlinger>& flinger, 169a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<Layer>& layer) 170a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { } 171a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 172a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> sur(new BSurface(mFlinger, this)); 173a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 176582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const 177582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{ 178b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mSurfaceTexture->getBufferQueue()->asBinder(); 179582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 180582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 181f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 184401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 187ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian if (err) { 188ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("unsupported pixelformat %d", format); 189ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian return err; 190ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian } 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 1931b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // XXX: we shouldn't rely on the DisplayHardware to do this 1941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 195ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 196ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 198ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 199ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 200ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 201ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 202ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 203ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 204ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 205cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 206eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 2073330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 20816f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 209a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); 210a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity = getOpacityForFormat(format); 211a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 212a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferSize(w, h); 213a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferFormat(format); 214b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 215ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 219f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const { 220f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Start with the SurfaceTexture's buffer crop... 221f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 224f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else if (mActiveBuffer != NULL){ 225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = Rect(mTransformedBounds.width(), mTransformedBounds.height()); 228f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 229f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // ... then reduce that in the same proportions as the window crop reduces 231f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // the window size. 232f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis const State& s(drawingState()); 23393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian if (!s.active.crop.isEmpty()) { 234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Transform the window crop to match the buffer coordinate system, 235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // which means using the inverse of the current transform set on the 236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // SurfaceTexture. 237f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis uint32_t invTransform = mCurrentTransform; 23893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winWidth = s.active.w; 23993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winHeight = s.active.h; 240f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis NATIVE_WINDOW_TRANSFORM_FLIP_H; 24393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winWidth = s.active.h; 24493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winHeight = s.active.w; 245f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 24693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian Rect winCrop = s.active.crop.transform(invTransform, 24793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian s.active.w, s.active.h); 248f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 249f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float xScale = float(crop.width()) / float(winWidth); 250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float yScale = float(crop.height()) / float(winHeight); 25193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.left += int(ceilf(float(winCrop.left) * xScale)); 25293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.top += int(ceilf(float(winCrop.top) * yScale)); 25393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 25493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 255f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 256f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 257f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 258f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 259f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 2603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopianvoid Layer::setGeometry(HWComposer::HWCLayerInterface& layer) 261a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 2623e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian LayerBaseClient::setGeometry(layer); 263a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 2643e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 2653e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 266a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 267a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can't do alpha-fade with the hwc HAL 268a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const State& s(drawingState()); 269a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (s.alpha < 0xFF) { 2703e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 271a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 272a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 27329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 27429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 27529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 27629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 27729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 278d992db3827016388e8069f5793b031153d423501Mathias Agopian * mTransform is already the composition of (2) and (3) 27929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 28029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 28129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 28229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 283d992db3827016388e8069f5793b031153d423501Mathias Agopian const Transform tr(mTransform * bufferOrientation); 28429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 28529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 28629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const uint32_t finalTransform = tr.getOrientation(); 28729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 288a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can only handle simple transformation 28929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian if (finalTransform & Transform::ROT_INVALID) { 2903e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 291a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 2923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setTransform(finalTransform); 293a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 2943e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setCrop(computeBufferCrop()); 295a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 296a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2973e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopianvoid Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { 298c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian const sp<GraphicBuffer>& buffer(mActiveBuffer); 2993e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 3003e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // layer yet, or if we ran out of memory 3013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setBuffer(buffer); 302c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 303c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 3041b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid Layer::onDraw(const DisplayHardware& hw, const Region& clip) const 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3061c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 3071c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 308a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 310179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 311179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 312179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 313179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 314179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 315179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 316179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 319f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 320f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian under.orSelf(layer->visibleRegionScreen); 327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 3311b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 335a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 3369575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis if (!isProtected()) { 337cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 338cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 339cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 340cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 341cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 342cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->setFilteringEnabled(useFiltering); 343cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->getTransformMatrix(textureMatrix); 344cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 345cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 346c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 347c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian GLenum filter = GL_NEAREST; 348cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis if (useFiltering) { 349c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian filter = GL_LINEAR; 3509575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis } 351c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 352c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 3539575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 354cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis glLoadMatrixf(textureMatrix); 3559575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 356c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 3574c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet glEnable(GL_TEXTURE_EXTERNAL_OES); 358a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 359c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 3609575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 3619575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glLoadIdentity(); 3629575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 363c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 364c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glEnable(GL_TEXTURE_2D); 365a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 366a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 3671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian drawWithOpenGL(hw, clip); 368a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 369c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 370c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 373ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 374ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 375ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 376ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 377ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 378ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 379ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 380a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) 381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 382a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 383a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 384ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 385a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormatInfo info; 386a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = getPixelFormatInfo(PixelFormat(format), &info); 387a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // in case of error (unknown format), we assume no blending 388a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return (err || info.h_alpha <= info.l_alpha); 389ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 390ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 391ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 392a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const 393a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 396db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 397a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 398db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 399a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 402a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mOpaqueLayer || mCurrentOpacity; 403a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 404a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 4057a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 4067a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 4087a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 4097a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4107a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 411b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4141c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4151c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4194824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian const bool sizeChanged = (temp.requested.w != front.requested.w) || 4204824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian (temp.requested.h != front.requested.h); 421a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 422a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 423cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 4249d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 425419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian "doTransaction: geometry (layer=%p), scalingMode=%d\n" 426419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 427419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 428419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 429419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 430419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian this, mCurrentScalingMode, 431419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.w, temp.active.h, 432419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.left, 433419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.top, 434419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.right, 435419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.bottom, 436419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getWidth(), 437419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getHeight(), 438419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.requested.w, temp.requested.h, 439b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.left, 440b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.top, 441b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.right, 442b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.bottom, 443b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getWidth(), 444b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getHeight(), 445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.w, front.active.h, 446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.left, 447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.top, 448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.right, 449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.bottom, 450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getWidth(), 451419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getHeight(), 452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.w, front.requested.h, 453b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.left, 454b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.top, 455b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.right, 456b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.bottom, 457b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.getWidth(), 458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.crop.getHeight()); 459a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 4602a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 4612a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian mSurfaceTexture->setDefaultBufferSize( 463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.w, temp.requested.h); 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 465cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 4660cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 4670cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian const bool resizePending = (temp.requested.w != temp.active.w) || 4690cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian (temp.requested.h != temp.active.h); 4700cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4710cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 4720cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // don't let LayerBase::doTransaction update the drawing state 4730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 4740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 4750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 4760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 4770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 4780cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 4790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 4800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 4820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 4830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 4840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 488a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const { 489933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 492a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const { 493a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return !mCurrentCrop.isEmpty(); 494a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 495a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 5014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 5024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return mQueuedFrames > 0; 50399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 50499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5071c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5093d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 51099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 51199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 51299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 51399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 51499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 51599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 5164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 5174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mPostedDirtyRegion.clear(); 51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return; 51999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 52099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 521351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 522db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis const bool oldOpacity = isOpaque(); 523351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 524db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 5253d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // signal another event if we have more frames pending 5263d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (android_atomic_dec(&mQueuedFrames) > 1) { 52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 5283d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis } 5293d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 5302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian struct Reject : public SurfaceTexture::BufferRejecter { 5312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 5322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 5332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 5342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 5352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions) 5362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 5372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions(recomputeVisibleRegions) { 5382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 5412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const BufferQueue::BufferItem& item) { 5422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 5432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 5442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 5472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 5482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 5502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 5512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 5522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 5532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 5572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 5582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 5602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 5612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 5622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 5632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 5642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 5652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n" 5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian this, bufWidth, bufHeight, item.mTransform, item.mScalingMode, 5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (!isFixedSize) { 6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 6044824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 618a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return; 619a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 620d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 621351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 622351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 623e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 624e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 625e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian return; 626e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 627da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6284824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 629702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 630e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian mFlinger->invalidateHwcGeometry(); 6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 635702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 636702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian Rect crop(mSurfaceTexture->getCurrentCrop()); 6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 639702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 640702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 641702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 642702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 643702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 644702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 645702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 646702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 647702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 648702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 649702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 650e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 651e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 652702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 653702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 654702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 655702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 656702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 657702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 658702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 659702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldOpacity != isOpaque()) { 660702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 661702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 662702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 663702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian // FIXME: mPostedDirtyRegion = dirty & bounds 6642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const Layer::State& front(drawingState()); 665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mPostedDirtyRegion.set(front.active.w, front.active.h); 666702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 667702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 668702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 669e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 6751c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 6761c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian Region postedRegion(mPostedDirtyRegion); 6784d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (!postedRegion.isEmpty()) { 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 6804d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (!visibleRegionScreen.isEmpty()) { 6814d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // The dirty region is given in the layer's coordinate space 6824d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // transform the dirty region by the surface's transformation 6834d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // and the global transformation. 6844d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian const Layer::State& s(drawingState()); 6854d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian const Transform tr(planeTransform * s.transform); 6864d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian postedRegion = tr.transform(postedRegion); 6874d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian 6884d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // At this point, the dirty region is in screen space. 6894d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // Make sure it's constrained by the visible region (which 6904d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian // is in screen space as well). 6914d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian postedRegion.andSelf(visibleRegionScreen); 6924d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian outDirtyRegion.orSelf(postedRegion); 6934d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 6981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 6991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 701a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 702a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 7031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 707a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 7081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 711ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n", 713a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian getTransformHint(), mQueuedFrames, mRefreshPending); 7151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 717d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 718a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mSurfaceTexture != 0) { 719a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->dump(result, " ", buffer, SIZE); 720bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 721d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 722d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 72382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 72482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 72582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian LayerBaseClient::dumpStats(result, buffer, SIZE); 72682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t o = mFrameLatencyOffset; 7271b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 72882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t period = hw.getRefreshPeriod(); 72982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\n", period); 73082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<128 ; i++) { 73182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t index = (o+i) % 128; 73282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_app = mFrameStats[index].timestamp; 73382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_set = mFrameStats[index].set; 73482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_vsync = mFrameStats[index].vsync; 73582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\t%lld\t%lld\n", 73682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_app, 73782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_vsync, 73882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_set); 73982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 74082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append("\n"); 74182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 74282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 74325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats() 74425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 74525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian LayerBaseClient::clearStats(); 74625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian memset(mFrameStats, 0, sizeof(mFrameStats)); 74725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 74825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 749a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 750b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 751a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: should we do something special if mSecure is set? 752a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mProtectedByApp) { 753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // need a hardware-protected path to external video sink 754a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 755b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 7563599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis usage |= GraphicBuffer::USAGE_HW_COMPOSER; 757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return usage; 758b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 759b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 760a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianuint32_t Layer::getTransformHint() const { 761a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian uint32_t orientation = 0; 762a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 7638d91b425078083d0e4967dcd8d669d9f7196123aJamie Gennis orientation = getPlaneOrientation(); 764a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (orientation & Transform::ROT_INVALID) { 765a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian orientation = 0; 766a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 767a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 768a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return orientation; 769a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 770a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 775