diff -r 000000000000 -r 6474c204b198 gfx/layers/composite/TiledContentHost.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/layers/composite/TiledContentHost.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_TILEDCONTENTHOST_H +#define GFX_TILEDCONTENTHOST_H + +#include // for uint16_t +#include // for FILE +#include // for swap +#include "ContentHost.h" // for ContentHost +#include "TiledLayerBuffer.h" // for TiledLayerBuffer, etc +#include "CompositableHost.h" +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE +#include "mozilla/RefPtr.h" // for RefPtr +#include "mozilla/gfx/Point.h" // for Point +#include "mozilla/gfx/Rect.h" // for Rect +#include "mozilla/gfx/Types.h" // for Filter +#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor +#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc +#include "mozilla/layers/TextureHost.h" // for TextureHost +#include "mozilla/layers/TiledContentClient.h" +#include "mozilla/mozalloc.h" // for operator delete +#include "nsRegion.h" // for nsIntRegion +#include "nscore.h" // for nsACString + +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 +#include +#endif + +class gfxReusableSurfaceWrapper; +struct nsIntPoint; +struct nsIntRect; +struct nsIntSize; + +namespace mozilla { +namespace gfx { +class Matrix4x4; +} + +namespace layers { + +class Compositor; +class ISurfaceAllocator; +class Layer; +class ThebesBufferData; +struct EffectChain; + + +class TileHost { +public: + // Constructs a placeholder TileHost. See the comments above + // TiledLayerBuffer for more information on what this is used for; + // essentially, this is a sentinel used to represent an invalid or blank + // tile. + TileHost() + : mSharedLock(nullptr) + , mTextureHost(nullptr) + {} + + // Constructs a TileHost from a gfxSharedReadLock and TextureHost. + TileHost(gfxSharedReadLock* aSharedLock, + TextureHost* aTextureHost) + : mSharedLock(aSharedLock) + , mTextureHost(aTextureHost) + {} + + TileHost(const TileHost& o) { + mTextureHost = o.mTextureHost; + mSharedLock = o.mSharedLock; + } + TileHost& operator=(const TileHost& o) { + if (this == &o) { + return *this; + } + mTextureHost = o.mTextureHost; + mSharedLock = o.mSharedLock; + return *this; + } + + bool operator== (const TileHost& o) const { + return mTextureHost == o.mTextureHost; + } + bool operator!= (const TileHost& o) const { + return mTextureHost != o.mTextureHost; + } + + bool IsPlaceholderTile() const { return mTextureHost == nullptr; } + + void ReadUnlock() { + if (mSharedLock) { + mSharedLock->ReadUnlock(); + } + } + + RefPtr mSharedLock; + RefPtr mTextureHost; +}; + +class TiledLayerBufferComposite + : public TiledLayerBuffer +{ + friend class TiledLayerBuffer; + +public: + typedef TiledLayerBuffer::Iterator Iterator; + + TiledLayerBufferComposite(); + TiledLayerBufferComposite(ISurfaceAllocator* aAllocator, + const SurfaceDescriptorTiles& aDescriptor, + const nsIntRegion& aOldPaintedRegion); + + TileHost GetPlaceholderTile() const { return TileHost(); } + + // Stores the absolute resolution of the containing frame, calculated + // by the sum of the resolutions of all parent layers' FrameMetrics. + const CSSToParentLayerScale& GetFrameResolution() { return mFrameResolution; } + + void ReadUnlock(); + + void ReleaseTextureHosts(); + + /** + * This will synchronously upload any necessary texture contents, making the + * sources immediately available for compositing. For texture hosts that + * don't have an internal buffer, this is unlikely to actually do anything. + */ + void Upload(); + + void SetCompositor(Compositor* aCompositor); + + bool HasDoubleBufferedTiles() { return mHasDoubleBufferedTiles; } + + bool IsValid() const { return !mUninitialized; } + +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 + virtual void SetReleaseFence(const android::sp& aReleaseFence); +#endif + + // Recycle callback for TextureHost. + // Used when TiledContentClient is present in client side. + static void RecycleCallback(TextureHost* textureHost, void* aClosure); + +protected: + TileHost ValidateTile(TileHost aTile, + const nsIntPoint& aTileRect, + const nsIntRegion& dirtyRect); + + // do nothing, the desctructor in the texture host takes care of releasing resources + void ReleaseTile(TileHost aTile) {} + + void SwapTiles(TileHost& aTileA, TileHost& aTileB) { std::swap(aTileA, aTileB); } + +private: + CSSToParentLayerScale mFrameResolution; + bool mHasDoubleBufferedTiles; + bool mUninitialized; +}; + +/** + * ContentHost for tiled Thebes layers. Since tiled layers are special snow + * flakes, we have a unique update process. All the textures that back the + * tiles are added in the usual way, but Updated is called on the host side + * in response to a message that describes the transaction for every tile. + * Composition happens in the normal way. + * + * TiledContentHost has a TiledLayerBufferComposite which keeps hold of the tiles. + * Each tile has a reference to a texture host. During the layers transaction, we + * receive a list of descriptors for the client-side tile buffer tiles + * (UseTiledLayerBuffer). If we receive two transactions before a composition, + * we immediately unlock and discard the unused buffer. + * + * When the content host is composited, we first validate the TiledLayerBuffer + * (Upload), which calls Updated on each tile's texture host to make sure the + * texture data has been uploaded. For single-buffered tiles, we unlock at this + * point, for double-buffered tiles we unlock and discard the last composited + * buffer after compositing a new one. Rendering takes us to RenderTile which + * is similar to Composite for non-tiled ContentHosts. + */ +class TiledContentHost : public ContentHost, + public TiledLayerComposer +{ +public: + TiledContentHost(const TextureInfo& aTextureInfo); + + ~TiledContentHost(); + + virtual LayerRenderState GetRenderState() MOZ_OVERRIDE + { + return LayerRenderState(); + } + + + virtual bool UpdateThebes(const ThebesBufferData& aData, + const nsIntRegion& aUpdated, + const nsIntRegion& aOldValidRegionBack, + nsIntRegion* aUpdatedRegionBack) + { + NS_ERROR("N/A for tiled layers"); + return false; + } + + const nsIntRegion& GetValidLowPrecisionRegion() const + { + return mLowPrecisionTiledBuffer.GetValidRegion(); + } + + void UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, + const SurfaceDescriptorTiles& aTiledDescriptor); + + void Composite(EffectChain& aEffectChain, + float aOpacity, + const gfx::Matrix4x4& aTransform, + const gfx::Filter& aFilter, + const gfx::Rect& aClipRect, + const nsIntRegion* aVisibleRegion = nullptr, + TiledLayerProperties* aLayerProperties = nullptr); + + virtual CompositableType GetType() { return BUFFER_TILED; } + + virtual TiledLayerComposer* AsTiledLayerComposer() MOZ_OVERRIDE { return this; } + + virtual void Attach(Layer* aLayer, + Compositor* aCompositor, + AttachFlags aFlags = NO_FLAGS) MOZ_OVERRIDE; + +#ifdef MOZ_DUMP_PAINTING + virtual void Dump(FILE* aFile=nullptr, + const char* aPrefix="", + bool aDumpHtml=false) MOZ_OVERRIDE; +#endif + + virtual void PrintInfo(nsACString& aTo, const char* aPrefix); + +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 + /** + * Store a fence that will signal when the current buffer is no longer being read. + * Similar to android's GLConsumer::setReleaseFence() + */ + virtual void SetReleaseFence(const android::sp& aReleaseFence) + { + mTiledBuffer.SetReleaseFence(aReleaseFence); + mLowPrecisionTiledBuffer.SetReleaseFence(aReleaseFence); + } +#endif + +private: + + void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, + EffectChain& aEffectChain, + float aOpacity, + const gfx::Filter& aFilter, + const gfx::Rect& aClipRect, + nsIntRegion aMaskRegion, + gfx::Matrix4x4 aTransform); + + // Renders a single given tile. + void RenderTile(const TileHost& aTile, + EffectChain& aEffectChain, + float aOpacity, + const gfx::Matrix4x4& aTransform, + const gfx::Filter& aFilter, + const gfx::Rect& aClipRect, + const nsIntRegion& aScreenRegion, + const nsIntPoint& aTextureOffset, + const nsIntSize& aTextureBounds); + + void EnsureTileStore() {} + + TiledLayerBufferComposite mTiledBuffer; + TiledLayerBufferComposite mLowPrecisionTiledBuffer; + TiledLayerBufferComposite mOldTiledBuffer; + TiledLayerBufferComposite mOldLowPrecisionTiledBuffer; + bool mPendingUpload; + bool mPendingLowPrecisionUpload; +}; + +} +} + +#endif