Layer.cpp revision 4fec873a98f7b4380720cd1ad006f74c8cdc73da
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), 63dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall mNeedHwcFence(false), 6482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameLatencyOffset(0), 655bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian mFormat(PIXEL_FORMAT_NONE), 661f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian mGLExtensions(GLExtensions::getInstance()), 67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer(true), 68b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSecure(false), 69933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian mProtectedByApp(false) 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentCrop.makeInvalid(); 72a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian glGenTextures(1, &mTextureName); 73e8696a40e09b24b634214684d18526187b316a2fJamie Gennis} 74e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 75ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallvoid Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) { 76ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (layer) { 77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd()); 78ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 79ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 80e8696a40e09b24b634214684d18526187b316a2fJamie Gennis if (mFrameLatencyNeeded) { 811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // we need a DisplayHardware for debugging only right now 821b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // XXX: should this be called per DisplayHardware? 831b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 8482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); 8582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].set = systemTime(); 8682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); 87e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 88e8696a40e09b24b634214684d18526187b316a2fJamie Gennis mFrameLatencyNeeded = false; 89e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 91d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef() 9396f0819f81293076e652792794a961543e6750d7Mathias Agopian{ 94a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LayerBaseClient::onFirstRef(); 95ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian 96a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 97a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian FrameQueuedListener(Layer* layer) : mLayer(layer) { } 98a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian private: 99a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<Layer> mLayer; 100a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual void onFrameAvailable() { 101a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<Layer> that(mLayer.promote()); 102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != 0) { 103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian that->onFrameQueued(); 104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 105a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 106a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 107b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 108b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam // Creates a custom BufferQueue for SurfaceTexture to use 109b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam sp<BufferQueue> bq = new SurfaceTextureLayer(); 110b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture = new SurfaceTexture(mTextureName, true, 111a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian GL_TEXTURE_EXTERNAL_OES, false, bq); 112b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 113b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 114a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 115a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setSynchronousMode(true); 116b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1177f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1187f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering" 119a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setBufferCountServer(2); 1207f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else 1217f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian mSurfaceTexture->setBufferCountServer(3); 122303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif 123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 12496f0819f81293076e652792794a961543e6750d7Mathias Agopian 125a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer() 126b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 127118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mFlinger->postMessageAsync( 128118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); 12996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 13096f0819f81293076e652792794a961543e6750d7Mathias Agopian 131a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() { 1323d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis android_atomic_inc(&mQueuedFrames); 13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 134579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 135579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 136d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 137d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list 138d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved() 139d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{ 140dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis mSurfaceTexture->abandon(); 14148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian} 142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 143a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) { 144a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis LayerBase::setName(name); 145a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis mSurfaceTexture->setName(name); 146a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis} 147a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis 148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface() 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 150a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian class BSurface : public BnSurface, public LayerCleaner { 151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian wp<const Layer> mOwner; 152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian virtual sp<ISurfaceTexture> getSurfaceTexture() const { 153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurfaceTexture> res; 154a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const Layer> that( mOwner.promote() ); 155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (that != NULL) { 156b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam res = that->mSurfaceTexture->getBufferQueue(); 157a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return res; 159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 160a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian public: 161a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian BSurface(const sp<SurfaceFlinger>& flinger, 162a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<Layer>& layer) 163a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : LayerCleaner(flinger, layer), mOwner(layer) { } 164a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian }; 165a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurface> sur(new BSurface(mFlinger, this)); 166a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian return sur; 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const 170582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{ 171b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mSurfaceTexture->getBufferQueue()->asBinder(); 172582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis} 173582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis 174f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 177401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // this surfaces pixel format 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 180ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian if (err) { 181ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("unsupported pixelformat %d", format); 182ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian return err; 183ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian } 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 185401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // the display's pixel format 1861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian // XXX: we shouldn't rely on the DisplayHardware to do this 1871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 188ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian uint32_t const maxSurfaceDims = min( 189ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian hw.getMaxTextureSize(), hw.getMaxViewportDims()); 190ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 191ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // never allow a surface larger than what our underlying GL implementation 192ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // can handle. 193ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 194ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 195ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian return BAD_VALUE; 196ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 198cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mFormat = format; 199eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian 2003330b203039dea366d4981db1408a460134b2d2cMathias Agopian mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 20116f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 202a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); 203a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mCurrentOpacity = getOpacityForFormat(format); 204a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 205a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferSize(w, h); 206a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->setDefaultBufferFormat(format); 207b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 208ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 212f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const { 213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Start with the SurfaceTexture's buffer crop... 214f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis Rect crop; 215f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (!mCurrentCrop.isEmpty()) { 216f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = mCurrentCrop; 217f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else if (mActiveBuffer != NULL){ 218f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 219f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } else { 2204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian crop.makeInvalid(); 2214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return crop; 222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 224f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // ... then reduce that in the same proportions as the window crop reduces 225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // the window size. 226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis const State& s(drawingState()); 22793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian if (!s.active.crop.isEmpty()) { 228f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // Transform the window crop to match the buffer coordinate system, 229f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // which means using the inverse of the current transform set on the 230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis // SurfaceTexture. 231f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis uint32_t invTransform = mCurrentTransform; 23293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winWidth = s.active.w; 23393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian int winHeight = s.active.h; 234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis NATIVE_WINDOW_TRANSFORM_FLIP_H; 23793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winWidth = s.active.h; 23893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian winHeight = s.active.w; 239f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 24093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian Rect winCrop = s.active.crop.transform(invTransform, 24193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian s.active.w, s.active.h); 242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float xScale = float(crop.width()) / float(winWidth); 244f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis float yScale = float(crop.height()) / float(winHeight); 24593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.left += int(ceilf(float(winCrop.left) * xScale)); 24693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.top += int(ceilf(float(winCrop.top) * yScale)); 24793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 24893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 249f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis } 250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis return crop; 252f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis} 253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis 2544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry( 2554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const DisplayHardware& hw, 2564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian HWComposer::HWCLayerInterface& layer) 257a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{ 2584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian LayerBaseClient::setGeometry(hw, layer); 259a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian 2603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // enable this layer 2613e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(false); 262a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 263a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can't do alpha-fade with the hwc HAL 264a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian const State& s(drawingState()); 265a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian if (s.alpha < 0xFF) { 2663e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 267a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 268a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 26929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian /* 27029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * Transformations are applied in this order: 27129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 1) buffer orientation/flip/mirror 27229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 2) state transformation (window manager) 27329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * 3) layer orientation (screen orientation) 27429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian * (NOTE: the matrices are multiplied in reverse order) 27529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian */ 27629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 27729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const Transform bufferOrientation(mCurrentTransform); 2784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(hw.getTransform() * s.transform * bufferOrientation); 27929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 28029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian // this gives us only the "orientation" component of the transform 28129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian const uint32_t finalTransform = tr.getOrientation(); 28229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian 283a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian // we can only handle simple transformation 28429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian if (finalTransform & Transform::ROT_INVALID) { 2853e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setSkip(true); 286a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian } else { 2873e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setTransform(finalTransform); 288a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian } 2893e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setCrop(computeBufferCrop()); 290a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian} 291a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2923e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopianvoid Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { 293c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian const sp<GraphicBuffer>& buffer(mActiveBuffer); 2943e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // NOTE: buffer can be NULL if the client never drew into this 2953e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian // layer yet, or if we ran out of memory 2963e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian layer.setBuffer(buffer); 297c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall} 298dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 299c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hallvoid Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) { 300c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall int fenceFd = -1; 301dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (mNeedHwcFence) { 302dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall sp<Fence> fence = mSurfaceTexture->getCurrentFence(); 303dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fence.get()) { 304c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall fenceFd = fence->dup(); 305dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fenceFd == -1) { 306dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW("failed to dup layer fence, skipping sync: %d", errno); 307dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 308dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 309dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall mNeedHwcFence = false; 310dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 311c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall layer.setAcquireFenceFd(fenceFd); 312c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian} 313c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian 3141b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid Layer::onDraw(const DisplayHardware& hw, const Region& clip) const 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3161c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 3171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 318a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (CC_UNLIKELY(mActiveBuffer == 0)) { 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // in fact never been drawn into. This happens frequently with 321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // SurfaceView because the WindowManager can't know when the client 322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // has drawn the first time. 323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // If there is nothing under us, we paint the screen in black, otherwise 325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // we just skip this update. 326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // figure out if there is something below us 328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region under; 329f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian const SurfaceFlinger::LayerVector& drawingLayers( 330f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian mFlinger->mDrawingState.layersSortedByZ); 331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const size_t count = drawingLayers.size(); 332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian for (size_t i=0 ; i<count ; ++i) { 333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian const sp<LayerBase>& layer(drawingLayers[i]); 334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (layer.get() == static_cast<LayerBase const*>(this)) 335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian break; 3364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian under.orSelf( hw.getTransform().transform(layer->visibleRegion) ); 337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian // if not everything below us is covered, we plug the holes! 339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian Region holes(clip.subtract(under)); 340179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian if (!holes.isEmpty()) { 3411b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian clearWithOpenGL(hw, holes, 0, 0, 0, 1); 342179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 345a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 346dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // TODO: replace this with a server-side wait 347dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall sp<Fence> fence = mSurfaceTexture->getCurrentFence(); 348dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall if (fence.get()) { 349dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall status_t err = fence->wait(Fence::TIMEOUT_NEVER); 350dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err); 351dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // Go ahead and draw the buffer anyway; no matter what we do the screen 352dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall // is probably going to have something visibly wrong. 353dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall } 354dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 3559575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis if (!isProtected()) { 356cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // TODO: we could be more subtle with isFixedSize() 357cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 358cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 359cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Query the texture matrix given our current filtering mode. 360cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis float textureMatrix[16]; 361cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->setFilteringEnabled(useFiltering); 362cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis mSurfaceTexture->getTransformMatrix(textureMatrix); 363cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis 364cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis // Set things up for texturing. 365c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 366c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian GLenum filter = GL_NEAREST; 367cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis if (useFiltering) { 368c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian filter = GL_LINEAR; 3699575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis } 370c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 371c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 3729575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 373cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis glLoadMatrixf(textureMatrix); 3749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 375c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 3764c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet glEnable(GL_TEXTURE_EXTERNAL_OES); 377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } else { 378c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 3799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_TEXTURE); 3809575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glLoadIdentity(); 3819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis glMatrixMode(GL_MODELVIEW); 382c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 383c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glEnable(GL_TEXTURE_2D); 384a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 385a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 3861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian drawWithOpenGL(hw, clip); 387a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 388c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 389c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian glDisable(GL_TEXTURE_2D); 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 392ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range 393ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and 394ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel 395ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into 396ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here. 397ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 398ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 399a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) 400ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{ 401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (HARDWARE_IS_DEVICE_FORMAT(format)) { 402a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return true; 403ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold } 404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian PixelFormatInfo info; 405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = getPixelFormatInfo(PixelFormat(format), &info); 406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // in case of error (unknown format), we assume no blending 407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return (err || info.h_alpha <= info.l_alpha); 408ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold} 409ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 410ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold 411a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const 412a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{ 413a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if we don't have a buffer yet, we're translucent regardless of the 414a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // layer's opaque flag. 415db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis if (mActiveBuffer == 0) { 416a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return false; 417db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis } 418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // if the layer has the opaque flag, then we're always opaque, 420a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // otherwise we use the current buffer's format. 421a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mOpaqueLayer || mCurrentOpacity; 422a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian} 423a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 4247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const 4257a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{ 426a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 4277a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis return (activeBuffer != 0) && 4287a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4297a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis} 430b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 4341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4384824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian const bool sizeChanged = (temp.requested.w != front.requested.w) || 4394824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian (temp.requested.h != front.requested.h); 440a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 441a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (sizeChanged) { 442cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the size changed, we need to ask our client to request a new buffer 4439d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(DEBUG_RESIZE, 444419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian "doTransaction: geometry (layer=%p), scalingMode=%d\n" 445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian this, mCurrentScalingMode, 450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.w, temp.active.h, 451419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.left, 452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.top, 453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.right, 454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.bottom, 455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getWidth(), 456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.active.crop.getHeight(), 457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian temp.requested.w, temp.requested.h, 458b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.left, 459b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.top, 460b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.right, 461b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.bottom, 462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getWidth(), 463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.crop.getHeight(), 464419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.w, front.active.h, 465419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.left, 466419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.top, 467419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.right, 468419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.bottom, 469419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getWidth(), 470419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.active.crop.getHeight(), 471419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.w, front.requested.h, 472b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.left, 473b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.top, 474b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.right, 475b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.bottom, 476b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian front.requested.crop.getWidth(), 477419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian front.requested.crop.getHeight()); 478a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 4792a0d5b608447a880beff5149805425f02691442bJamie Gennis // record the new size, form this point on, when the client request 4802a0d5b608447a880beff5149805425f02691442bJamie Gennis // a buffer, it'll get the new size. 481b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian mSurfaceTexture->setDefaultBufferSize( 482b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian temp.requested.w, temp.requested.h); 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 484cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 4850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (!isFixedSize()) { 4860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian const bool resizePending = (temp.requested.w != temp.active.w) || 4880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian (temp.requested.h != temp.active.h); 4890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian if (resizePending) { 4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // don't let LayerBase::doTransaction update the drawing state 4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // if we have a pending resize, unless we are in fixed-size mode. 4930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // the drawing state will be updated only once we receive a buffer 4940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // with the correct size. 4950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // 4960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // in particular, we want to make sure the clip (which is part 4970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // of the geometry state) is latched together with the size but is 4980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian // latched immediately when no resizing is involved. 4990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 5000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian flags |= eDontUpdateGeometryState; 5010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 5020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian } 5030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 507a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const { 508933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian} 510a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const { 512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return !mCurrentCrop.isEmpty(); 513a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 514a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() { 5204d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian mRefreshPending = false; 5214d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return mQueuedFrames > 0; 52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 5244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions) 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5261c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 5271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 5284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region outDirtyRegion; 5293d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (mQueuedFrames > 0) { 53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // if we've already called updateTexImage() without going through 53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // a composition step, we have to skip this layer at this point 53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // because we cannot call updateTeximage() without a corresponding 53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // compositionComplete() call. 53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // we'll trigger an update in onPreComposition(). 5364d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian if (mRefreshPending) { 5374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 540351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // Capture the old state of the layer for comparisons later 541db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis const bool oldOpacity = isOpaque(); 542351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 543db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis 5443d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // signal another event if we have more frames pending 5453d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis if (android_atomic_dec(&mQueuedFrames) > 1) { 54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mFlinger->signalLayerUpdate(); 5473d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis } 5483d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 5492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian struct Reject : public SurfaceTexture::BufferRejecter { 5502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& front; 5512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Layer::State& current; 5522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions; 5532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject(Layer::State& front, Layer::State& current, 5542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool& recomputeVisibleRegions) 5552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian : front(front), current(current), 5562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions(recomputeVisibleRegions) { 5572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian virtual bool reject(const sp<GraphicBuffer>& buf, 5602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const BufferQueue::BufferItem& item) { 5612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (buf == NULL) { 5622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 5632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufWidth = buf->getWidth(); 5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian uint32_t bufHeight = buf->getHeight(); 5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // check that we received a buffer of the right size 5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // (Take the buffer's orientation into account) 5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (item.mTransform & Transform::ROT_90) { 5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian swap(bufWidth, bufHeight); 5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active != front.requested) { 5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (isFixedSize || 5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian (bufWidth == front.requested.w && 5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian bufHeight == front.requested.h)) 5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian { 5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // Here we pretend the transaction happened by updating the 5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // current and drawing states. Drawing state is only accessed 5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // in this thread, no need to have it locked 5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active = front.requested; 5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // We also need to update the current state so that 5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we don't end-up overwriting the drawing state with 5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // this stale current state during the next transaction 5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // 5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // NOTE: We don't need to hold the transaction lock here 5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // because State::active is only accessed from this thread. 5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian current.active = front.active; 5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // recompute visible region 5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian recomputeVisibleRegions = true; 5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian ALOGD_IF(DEBUG_RESIZE, 6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n" 6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian this, bufWidth, bufHeight, item.mTransform, item.mScalingMode, 6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.w, front.active.h, 6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.left, 6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.top, 6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.right, 6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.bottom, 6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getWidth(), 6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.crop.getHeight(), 6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.w, front.requested.h, 6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.left, 6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.top, 6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.right, 6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.bottom, 6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getWidth(), 6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.requested.crop.getHeight()); 6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (!isFixedSize) { 6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (front.active.w != bufWidth || 6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian front.active.h != bufHeight) { 6234824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian // reject this buffer 6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return true; 6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return false; 6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian }; 6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 6344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // XXX: not sure if setTransformHint belongs here 6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // it should only be needed when the main screen orientation changes 6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mSurfaceTexture->setTransformHint(getTransformHint()); 6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 639a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // something happened! 640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian recomputeVisibleRegions = true; 6414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 643d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 644351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis // update the active buffer 645351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 646e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (mActiveBuffer == NULL) { 647e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian // this can only happen if the very first buffer was rejected. 6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 649e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian } 650da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian 6514824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian mRefreshPending = true; 652702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFrameLatencyNeeded = true; 653dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall mNeedHwcFence = true; 654e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian if (oldActiveBuffer == NULL) { 6552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // the first time we receive a buffer, we need to trigger a 6562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // geometry invalidation. 6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian mFlinger->invalidateHwcGeometry(); 6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 659702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 660702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian Rect crop(mSurfaceTexture->getCurrentCrop()); 6612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 6622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 663702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if ((crop != mCurrentCrop) || 664702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (transform != mCurrentTransform) || 665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian (scalingMode != mCurrentScalingMode)) 666702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian { 667702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentCrop = crop; 668702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentTransform = transform; 669702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentScalingMode = scalingMode; 670702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 671702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 672702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 673702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldActiveBuffer != NULL) { 674e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufWidth = mActiveBuffer->getWidth(); 675e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian uint32_t bufHeight = mActiveBuffer->getHeight(); 676702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (bufWidth != uint32_t(oldActiveBuffer->width) || 677702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian bufHeight != uint32_t(oldActiveBuffer->height)) { 678702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mFlinger->invalidateHwcGeometry(); 679702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 680702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 682702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 683702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian if (oldOpacity != isOpaque()) { 684702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian recomputeVisibleRegions = true; 685702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian } 686702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian 687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 688702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // FIXME: postedRegion should be dirty & bounds 6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Layer::State& front(drawingState()); 6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion(Rect(front.active.w, front.active.h)); 6931c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the dirty region to window-manager space 6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian outDirtyRegion = (front.transform.transform(dirtyRegion)); 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian return outDirtyRegion; 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const 7011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 7021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian LayerBaseClient::dump(result, buffer, SIZE); 7031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 704a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<const GraphicBuffer> buf0(mActiveBuffer); 705a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian uint32_t w0=0, h0=0, s0=0, f0=0; 7061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian if (buf0 != 0) { 7071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian w0 = buf0->getWidth(); 7081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian h0 = buf0->getHeight(); 7091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian s0 = buf0->getStride(); 710a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian f0 = buf0->format; 7111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 7121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian snprintf(buffer, SIZE, 7131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian " " 714ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n", 716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mFormat, w0, h0, s0,f0, 71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian getTransformHint(), mQueuedFrames, mRefreshPending); 7181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian result.append(buffer); 720d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 721a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mSurfaceTexture != 0) { 722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTexture->dump(result, " ", buffer, SIZE); 723bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 724d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian} 725d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 72682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 72782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 72882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian LayerBaseClient::dumpStats(result, buffer, SIZE); 72982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t o = mFrameLatencyOffset; 7301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 73182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t period = hw.getRefreshPeriod(); 73282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\n", period); 73382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<128 ; i++) { 73482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t index = (o+i) % 128; 73582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_app = mFrameStats[index].timestamp; 73682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_set = mFrameStats[index].set; 73782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t time_vsync = mFrameStats[index].vsync; 73882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.appendFormat("%lld\t%lld\t%lld\n", 73982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_app, 74082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_vsync, 74182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian time_set); 74282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 74382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian result.append("\n"); 74482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 74582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 74625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats() 74725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 74825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian LayerBaseClient::clearStats(); 74925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian memset(mFrameStats, 0, sizeof(mFrameStats)); 75025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 75125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 752a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const 753b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 754a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: should we do something special if mSecure is set? 755a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mProtectedByApp) { 756a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // need a hardware-protected path to external video sink 757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian usage |= GraphicBuffer::USAGE_PROTECTED; 758b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 7593599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis usage |= GraphicBuffer::USAGE_HW_COMPOSER; 760a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return usage; 761b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 763a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianuint32_t Layer::getTransformHint() const { 764a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian uint32_t orientation = 0; 765a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (!mFlinger->mDebugDisableTransformHint) { 7664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // The transform hint is used to improve performance on the main 7674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // display -- we can only have a single transform hint, it cannot 7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // apply to all displays. 7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // This is why we use the default display here. This is not an 7704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // oversight. 7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); 7724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform& planeTransform(hw.getTransform()); 7734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian orientation = planeTransform.getOrientation(); 774a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian if (orientation & Transform::ROT_INVALID) { 775a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian orientation = 0; 776a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 777a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian } 778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return orientation; 779a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian} 780a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 785