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