Layer.cpp revision ef19414bd8b77a26f5751f3845be79025a8263fe
16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2007 The Android Open Source Project 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Licensed under the Apache License, Version 2.0 (the "License"); 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * you may not use this file except in compliance with the License. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * You may obtain a copy of the License at 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * http://www.apache.org/licenses/LICENSE-2.0 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Unless required by applicable law or agreed to in writing, software 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * distributed under the License is distributed on an "AS IS" BASIS, 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * See the License for the specific language governing permissions and 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * limitations under the License. 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ATRACE_TAG ATRACE_TAG_GRAPHICS 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdlib.h> 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdint.h> 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <sys/types.h> 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <math.h> 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/compiler.h> 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/native_handle.h> 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/properties.h> 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Errors.h> 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Log.h> 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/StopWatch.h> 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Trace.h> 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <ui/GraphicBuffer.h> 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <ui/PixelFormat.h> 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <gui/Surface.h> 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "clz.h" 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "DisplayHardware/DisplayHardware.h" 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "DisplayHardware/HWComposer.h" 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "GLExtensions.h" 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "Layer.h" 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "SurfaceFlinger.h" 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "SurfaceTextureLayer.h" 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DEBUG_RESIZE 0 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace android { 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------------------------------- 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLayer::Layer(SurfaceFlinger* flinger, 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DisplayID display, const sp<Client>& client) 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : LayerBaseClient(flinger, display, client), 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mTextureName(-1U), 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mQueuedFrames(0), 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mCurrentTransform(0), 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mCurrentOpacity(true), 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mRefreshPending(false), 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameLatencyNeeded(false), 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameLatencyOffset(0), 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFormat(PIXEL_FORMAT_NONE), 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mGLExtensions(GLExtensions::getInstance()), 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mOpaqueLayer(true), 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mNeedsDithering(false), 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSecure(false), 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mProtectedByApp(false) 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mCurrentCrop.makeInvalid(); 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glGenTextures(1, &mTextureName); 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (layer) { 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd()); 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mFrameLatencyNeeded) { 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DisplayHardware& hw(graphicPlane(0).displayHardware()); 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameStats[mFrameLatencyOffset].set = systemTime(); 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFrameLatencyNeeded = false; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onFirstRef() 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LayerBaseClient::onFirstRef(); 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FrameQueuedListener(Layer* layer) : mLayer(layer) { } 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private: 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org wp<Layer> mLayer; 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual void onFrameAvailable() { 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<Layer> that(mLayer.promote()); 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (that != 0) { 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org that->onFrameQueued(); 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Creates a custom BufferQueue for SurfaceTexture to use 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<BufferQueue> bq = new SurfaceTextureLayer(); 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture = new SurfaceTexture(mTextureName, true, 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GL_TEXTURE_EXTERNAL_OES, false, bq); 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setSynchronousMode(true); 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#warning "disabling triple buffering" 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setBufferCountServer(2); 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setBufferCountServer(3); 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLayer::~Layer() 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFlinger->postMessageAsync( 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onFrameQueued() { 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org android_atomic_inc(&mQueuedFrames); 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFlinger->signalLayerUpdate(); 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// called with SurfaceFlinger::mStateLock as soon as the layer is entered 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// in the purgatory list 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onRemoved() 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->abandon(); 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setName(const String8& name) { 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LayerBase::setName(name); 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setName(name); 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::validateVisibility(const Transform& globalTransform) { 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LayerBase::validateVisibility(globalTransform); 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This optimization allows the SurfaceTexture to bake in 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the rotation so hardware overlays can be used 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setTransformHint(getTransformHint()); 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgsp<ISurface> Layer::createSurface() 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org class BSurface : public BnSurface, public LayerCleaner { 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org wp<const Layer> mOwner; 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual sp<ISurfaceTexture> getSurfaceTexture() const { 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<ISurfaceTexture> res; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<const Layer> that( mOwner.promote() ); 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (that != NULL) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res = that->mSurfaceTexture->getBufferQueue(); 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return res; 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public: 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org BSurface(const sp<SurfaceFlinger>& flinger, 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const sp<Layer>& layer) 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : LayerCleaner(flinger, layer), mOwner(layer) { } 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<ISurface> sur(new BSurface(mFlinger, this)); 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return sur; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgwp<IBinder> Layer::getSurfaceTextureBinder() const 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mSurfaceTexture->getBufferQueue()->asBinder(); 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatus_t Layer::setBuffers( uint32_t w, uint32_t h, 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PixelFormat format, uint32_t flags) 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // this surfaces pixel format 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PixelFormatInfo info; 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status_t err = getPixelFormatInfo(format, &info); 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err) { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ALOGE("unsupported pixelformat %d", format); 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return err; 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the display's pixel format 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t const maxSurfaceDims = min( 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hw.getMaxTextureSize(), hw.getMaxViewportDims()); 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // never allow a surface larger than what our underlying GL implementation 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // can handle. 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return BAD_VALUE; 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PixelFormatInfo displayInfo; 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getPixelFormatInfo(hw.getFormat(), &displayInfo); 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t hwFlags = hw.getFlags(); 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFormat = format; 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mCurrentOpacity = getOpacityForFormat(format); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setDefaultBufferSize(w, h); 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setDefaultBufferFormat(format); 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we use the red index 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mNeedsDithering = layerRedsize > displayRedSize; 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NO_ERROR; 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgRect Layer::computeBufferCrop() const { 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Start with the SurfaceTexture's buffer crop... 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Rect crop; 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!mCurrentCrop.isEmpty()) { 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop = mCurrentCrop; 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (mActiveBuffer != NULL){ 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop = Rect(mTransformedBounds.width(), mTransformedBounds.height()); 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ... then reduce that in the same proportions as the window crop reduces 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the window size. 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const State& s(drawingState()); 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!s.active.crop.isEmpty()) { 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Transform the window crop to match the buffer coordinate system, 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // which means using the inverse of the current transform set on the 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // SurfaceTexture. 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t invTransform = mCurrentTransform; 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int winWidth = s.active.w; 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int winHeight = s.active.h; 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NATIVE_WINDOW_TRANSFORM_FLIP_H; 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org winWidth = s.active.h; 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org winHeight = s.active.w; 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Rect winCrop = s.active.crop.transform(invTransform, 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s.active.w, s.active.h); 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float xScale = float(crop.width()) / float(winWidth); 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float yScale = float(crop.height()) / float(winHeight); 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop.left += int(ceilf(float(winCrop.left) * xScale)); 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop.top += int(ceilf(float(winCrop.top) * yScale)); 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return crop; 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setGeometry(HWComposer::HWCLayerInterface& layer) 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LayerBaseClient::setGeometry(layer); 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // enable this layer 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setSkip(false); 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we can't do alpha-fade with the hwc HAL 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const State& s(drawingState()); 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (s.alpha < 0xFF) { 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setSkip(true); 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transformations are applied in this order: 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1) buffer orientation/flip/mirror 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2) state transformation (window manager) 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3) layer orientation (screen orientation) 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * mTransform is already the composition of (2) and (3) 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (NOTE: the matrices are multiplied in reverse order) 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Transform bufferOrientation(mCurrentTransform); 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Transform tr(mTransform * bufferOrientation); 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // this gives us only the "orientation" component of the transform 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t finalTransform = tr.getOrientation(); 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we can only handle simple transformation 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (finalTransform & Transform::ROT_INVALID) { 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setSkip(true); 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setTransform(finalTransform); 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setCrop(computeBufferCrop()); 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const sp<GraphicBuffer>& buffer(mActiveBuffer); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NOTE: buffer can be NULL if the client never drew into this 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // layer yet, or if we ran out of memory 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org layer.setBuffer(buffer); 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onDraw(const Region& clip) const 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ATRACE_CALL(); 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (CC_UNLIKELY(mActiveBuffer == 0)) { 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the texture has not been created yet, this Layer has 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in fact never been drawn into. This happens frequently with 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // SurfaceView because the WindowManager can't know when the client 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // has drawn the first time. 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If there is nothing under us, we paint the screen in black, otherwise 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we just skip this update. 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // figure out if there is something below us 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Region under; 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const SurfaceFlinger::LayerVector& drawingLayers( 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFlinger->mDrawingState.layersSortedByZ); 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const size_t count = drawingLayers.size(); 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (size_t i=0 ; i<count ; ++i) { 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const sp<LayerBase>& layer(drawingLayers[i]); 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (layer.get() == static_cast<LayerBase const*>(this)) 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org under.orSelf(layer->visibleRegionScreen); 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if not everything below us is covered, we plug the holes! 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Region holes(clip.subtract(under)); 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!holes.isEmpty()) { 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clearWithOpenGL(holes, 0, 0, 0, 1); 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!isProtected()) { 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: we could be more subtle with isFixedSize() 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Query the texture matrix given our current filtering mode. 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org float textureMatrix[16]; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setFilteringEnabled(useFiltering); 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->getTransformMatrix(textureMatrix); 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set things up for texturing. 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GLenum filter = GL_NEAREST; 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (useFiltering) { 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter = GL_LINEAR; 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glMatrixMode(GL_TEXTURE); 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glLoadMatrixf(textureMatrix); 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glMatrixMode(GL_MODELVIEW); 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glDisable(GL_TEXTURE_2D); 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glEnable(GL_TEXTURE_EXTERNAL_OES); 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glMatrixMode(GL_TEXTURE); 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glLoadIdentity(); 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glMatrixMode(GL_MODELVIEW); 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glDisable(GL_TEXTURE_EXTERNAL_OES); 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glEnable(GL_TEXTURE_2D); 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org drawWithOpenGL(clip); 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glDisable(GL_TEXTURE_EXTERNAL_OES); 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org glDisable(GL_TEXTURE_2D); 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// As documented in libhardware header, formats in the range 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 0x100 - 0x1FF are specific to the HAL implementation, and 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// are known to have no alpha channel 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TODO: move definition for device-specific range into 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// hardware.h, instead of using hard-coded values here. 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::getOpacityForFormat(uint32_t format) 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HARDWARE_IS_DEVICE_FORMAT(format)) { 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return true; 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PixelFormatInfo info; 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status_t err = getPixelFormatInfo(PixelFormat(format), &info); 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in case of error (unknown format), we assume no blending 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (err || info.h_alpha <= info.l_alpha); 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isOpaque() const 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if we don't have a buffer yet, we're translucent regardless of the 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // layer's opaque flag. 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mActiveBuffer == 0) { 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return false; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if the layer has the opaque flag, then we're always opaque, 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // otherwise we use the current buffer's format. 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mOpaqueLayer || mCurrentOpacity; 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isProtected() const 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (activeBuffer != 0) && 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguint32_t Layer::doTransaction(uint32_t flags) 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ATRACE_CALL(); 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Layer::State& front(drawingState()); 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Layer::State& temp(currentState()); 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const bool sizeChanged = (temp.requested.w != front.requested.w) || 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (temp.requested.h != front.requested.h); 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sizeChanged) { 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the size changed, we need to ask our client to request a new buffer 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ALOGD_IF(DEBUG_RESIZE, 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "doTransaction: geometry (layer=%p), scalingMode=%d\n" 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this, mCurrentScalingMode, 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.w, temp.active.h, 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.left, 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.top, 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.right, 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.bottom, 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.getWidth(), 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.active.crop.getHeight(), 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.w, temp.requested.h, 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.left, 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.top, 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.right, 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.bottom, 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.getWidth(), 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.crop.getHeight(), 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.w, front.active.h, 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.left, 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.top, 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.right, 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.bottom, 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.getWidth(), 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.active.crop.getHeight(), 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.w, front.requested.h, 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.left, 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.top, 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.right, 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.bottom, 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.getWidth(), 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org front.requested.crop.getHeight()); 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // record the new size, form this point on, when the client request 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // a buffer, it'll get the new size. 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mSurfaceTexture->setDefaultBufferSize( 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp.requested.w, temp.requested.h); 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!isFixedSize()) { 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const bool resizePending = (temp.requested.w != temp.active.w) || 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (temp.requested.h != temp.active.h); 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (resizePending) { 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // don't let LayerBase::doTransaction update the drawing state 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if we have a pending resize, unless we are in fixed-size mode. 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the drawing state will be updated only once we receive a buffer 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // with the correct size. 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in particular, we want to make sure the clip (which is part 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // of the geometry state) is latched together with the size but is 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // latched immediately when no resizing is involved. 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags |= eDontUpdateGeometryState; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return LayerBase::doTransaction(flags); 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isFixedSize() const { 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isCropped() const { 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return !mCurrentCrop.isEmpty(); 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---------------------------------------------------------------------------- 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// pageflip handling... 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---------------------------------------------------------------------------- 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::onPreComposition() { 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mRefreshPending = false; 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mQueuedFrames > 0; 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ATRACE_CALL(); 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mQueuedFrames > 0) { 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if we've already called updateTexImage() without going through 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // a composition step, we have to skip this layer at this point 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // because we cannot call updateTeximage() without a corresponding 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // compositionComplete() call. 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we'll trigger an update in onPreComposition(). 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mRefreshPending) { 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mPostedDirtyRegion.clear(); 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Capture the old state of the layer for comparisons later 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const bool oldOpacity = isOpaque(); 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // signal another event if we have more frames pending 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (android_atomic_dec(&mQueuedFrames) > 1) { 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mFlinger->signalLayerUpdate(); 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org struct Reject : public SurfaceTexture::BufferRejecter { 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Layer::State& front; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Layer::State& current; 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool& recomputeVisibleRegions; 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Reject(Layer::State& front, Layer::State& current, 541 bool& recomputeVisibleRegions) 542 : front(front), current(current), 543 recomputeVisibleRegions(recomputeVisibleRegions) { 544 } 545 546 virtual bool reject(const sp<GraphicBuffer>& buf, 547 const BufferQueue::BufferItem& item) { 548 if (buf == NULL) { 549 return false; 550 } 551 552 uint32_t bufWidth = buf->getWidth(); 553 uint32_t bufHeight = buf->getHeight(); 554 555 // check that we received a buffer of the right size 556 // (Take the buffer's orientation into account) 557 if (item.mTransform & Transform::ROT_90) { 558 swap(bufWidth, bufHeight); 559 } 560 561 562 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 563 if (front.active != front.requested) { 564 565 if (isFixedSize || 566 (bufWidth == front.requested.w && 567 bufHeight == front.requested.h)) 568 { 569 // Here we pretend the transaction happened by updating the 570 // current and drawing states. Drawing state is only accessed 571 // in this thread, no need to have it locked 572 front.active = front.requested; 573 574 // We also need to update the current state so that 575 // we don't end-up overwriting the drawing state with 576 // this stale current state during the next transaction 577 // 578 // NOTE: We don't need to hold the transaction lock here 579 // because State::active is only accessed from this thread. 580 current.active = front.active; 581 582 // recompute visible region 583 recomputeVisibleRegions = true; 584 } 585 586 ALOGD_IF(DEBUG_RESIZE, 587 "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n" 588 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 589 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 590 this, bufWidth, bufHeight, item.mTransform, item.mScalingMode, 591 front.active.w, front.active.h, 592 front.active.crop.left, 593 front.active.crop.top, 594 front.active.crop.right, 595 front.active.crop.bottom, 596 front.active.crop.getWidth(), 597 front.active.crop.getHeight(), 598 front.requested.w, front.requested.h, 599 front.requested.crop.left, 600 front.requested.crop.top, 601 front.requested.crop.right, 602 front.requested.crop.bottom, 603 front.requested.crop.getWidth(), 604 front.requested.crop.getHeight()); 605 } 606 607 if (!isFixedSize) { 608 if (front.active.w != bufWidth || 609 front.active.h != bufHeight) { 610 // reject this buffer 611 return true; 612 } 613 } 614 return false; 615 } 616 }; 617 618 619 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 620 621 if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 622 // something happened! 623 recomputeVisibleRegions = true; 624 return; 625 } 626 627 // update the active buffer 628 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 629 if (mActiveBuffer == NULL) { 630 // this can only happen if the very first buffer was rejected. 631 return; 632 } 633 634 mRefreshPending = true; 635 mFrameLatencyNeeded = true; 636 if (oldActiveBuffer == NULL) { 637 // the first time we receive a buffer, we need to trigger a 638 // geometry invalidation. 639 mFlinger->invalidateHwcGeometry(); 640 } 641 642 Rect crop(mSurfaceTexture->getCurrentCrop()); 643 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 644 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 645 if ((crop != mCurrentCrop) || 646 (transform != mCurrentTransform) || 647 (scalingMode != mCurrentScalingMode)) 648 { 649 mCurrentCrop = crop; 650 mCurrentTransform = transform; 651 mCurrentScalingMode = scalingMode; 652 mFlinger->invalidateHwcGeometry(); 653 } 654 655 if (oldActiveBuffer != NULL) { 656 uint32_t bufWidth = mActiveBuffer->getWidth(); 657 uint32_t bufHeight = mActiveBuffer->getHeight(); 658 if (bufWidth != uint32_t(oldActiveBuffer->width) || 659 bufHeight != uint32_t(oldActiveBuffer->height)) { 660 mFlinger->invalidateHwcGeometry(); 661 } 662 } 663 664 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 665 if (oldOpacity != isOpaque()) { 666 recomputeVisibleRegions = true; 667 } 668 669 // FIXME: mPostedDirtyRegion = dirty & bounds 670 const Layer::State& front(drawingState()); 671 mPostedDirtyRegion.set(front.active.w, front.active.h); 672 673 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 674 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 675 } 676} 677 678void Layer::unlockPageFlip( 679 const Transform& planeTransform, Region& outDirtyRegion) 680{ 681 ATRACE_CALL(); 682 683 Region postedRegion(mPostedDirtyRegion); 684 if (!postedRegion.isEmpty()) { 685 mPostedDirtyRegion.clear(); 686 if (!visibleRegionScreen.isEmpty()) { 687 // The dirty region is given in the layer's coordinate space 688 // transform the dirty region by the surface's transformation 689 // and the global transformation. 690 const Layer::State& s(drawingState()); 691 const Transform tr(planeTransform * s.transform); 692 postedRegion = tr.transform(postedRegion); 693 694 // At this point, the dirty region is in screen space. 695 // Make sure it's constrained by the visible region (which 696 // is in screen space as well). 697 postedRegion.andSelf(visibleRegionScreen); 698 outDirtyRegion.orSelf(postedRegion); 699 } 700 } 701} 702 703void Layer::dump(String8& result, char* buffer, size_t SIZE) const 704{ 705 LayerBaseClient::dump(result, buffer, SIZE); 706 707 sp<const GraphicBuffer> buf0(mActiveBuffer); 708 uint32_t w0=0, h0=0, s0=0, f0=0; 709 if (buf0 != 0) { 710 w0 = buf0->getWidth(); 711 h0 = buf0->getHeight(); 712 s0 = buf0->getStride(); 713 f0 = buf0->format; 714 } 715 snprintf(buffer, SIZE, 716 " " 717 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 718 " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n", 719 mFormat, w0, h0, s0,f0, 720 getTransformHint(), mQueuedFrames, mRefreshPending); 721 722 result.append(buffer); 723 724 if (mSurfaceTexture != 0) { 725 mSurfaceTexture->dump(result, " ", buffer, SIZE); 726 } 727} 728 729void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 730{ 731 LayerBaseClient::dumpStats(result, buffer, SIZE); 732 const size_t o = mFrameLatencyOffset; 733 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 734 const nsecs_t period = hw.getRefreshPeriod(); 735 result.appendFormat("%lld\n", period); 736 for (size_t i=0 ; i<128 ; i++) { 737 const size_t index = (o+i) % 128; 738 const nsecs_t time_app = mFrameStats[index].timestamp; 739 const nsecs_t time_set = mFrameStats[index].set; 740 const nsecs_t time_vsync = mFrameStats[index].vsync; 741 result.appendFormat("%lld\t%lld\t%lld\n", 742 time_app, 743 time_vsync, 744 time_set); 745 } 746 result.append("\n"); 747} 748 749void Layer::clearStats() 750{ 751 LayerBaseClient::clearStats(); 752 memset(mFrameStats, 0, sizeof(mFrameStats)); 753} 754 755uint32_t Layer::getEffectiveUsage(uint32_t usage) const 756{ 757 // TODO: should we do something special if mSecure is set? 758 if (mProtectedByApp) { 759 // need a hardware-protected path to external video sink 760 usage |= GraphicBuffer::USAGE_PROTECTED; 761 } 762 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 763 return usage; 764} 765 766uint32_t Layer::getTransformHint() const { 767 uint32_t orientation = 0; 768 if (!mFlinger->mDebugDisableTransformHint) { 769 orientation = getPlaneOrientation(); 770 if (orientation & Transform::ROT_INVALID) { 771 orientation = 0; 772 } 773 } 774 return orientation; 775} 776 777// --------------------------------------------------------------------------- 778 779 780}; // namespace android 781