diff options
Diffstat (limited to 'gfx/layers/composite/CompositableHost.h')
-rw-r--r-- | gfx/layers/composite/CompositableHost.h | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h new file mode 100644 index 0000000000..6f749d76b8 --- /dev/null +++ b/gfx/layers/composite/CompositableHost.h @@ -0,0 +1,278 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 MOZILLA_GFX_BUFFERHOST_H +#define MOZILLA_GFX_BUFFERHOST_H + +#include <stdint.h> // for uint64_t +#include <stdio.h> // for FILE +#include "gfxRect.h" // for gfxRect +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc +#include "mozilla/Attributes.h" // for override +#include "mozilla/RefPtr.h" // for RefPtr, RefCounted, etc +#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4 +#include "mozilla/gfx/Point.h" // for Point +#include "mozilla/gfx/Polygon.h" // for Polygon +#include "mozilla/gfx/Rect.h" // for Rect +#include "mozilla/gfx/Types.h" // for SamplingFilter +#include "mozilla/ipc/ProtocolUtils.h" +#include "mozilla/layers/Compositor.h" // for Compositor +#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc +#include "mozilla/layers/Effects.h" // for Texture Effect +#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc +#include "mozilla/layers/LayersMessages.h" +#include "mozilla/layers/TextureHost.h" // for TextureHost +#include "mozilla/mozalloc.h" // for operator delete +#include "nsCOMPtr.h" // for already_AddRefed +#include "nsRegion.h" // for nsIntRegion +#include "nscore.h" // for nsACString +#include "Units.h" // for CSSToScreenScale + +namespace mozilla { +namespace gfx { +class DataSourceSurface; +} // namespace gfx + +namespace layers { + +class Layer; +class LayerComposite; +class ImageHost; +class Compositor; +class ThebesBufferData; +class TiledContentHost; +class CompositableParentManager; +class WebRenderImageHost; +class ContentHost; +class ContentHostTexture; +class HostLayerManager; +struct EffectChain; + +struct ImageCompositeNotificationInfo { + base::ProcessId mImageBridgeProcessId; + ImageCompositeNotification mNotification; +}; + +struct AsyncCompositableRef { + AsyncCompositableRef() : mProcessId(mozilla::ipc::kInvalidProcessId) {} + AsyncCompositableRef(base::ProcessId aProcessId, + const CompositableHandle& aHandle) + : mProcessId(aProcessId), mHandle(aHandle) {} + explicit operator bool() const { return !!mHandle; } + base::ProcessId mProcessId; + CompositableHandle mHandle; +}; + +/** + * The compositor-side counterpart to CompositableClient. Responsible for + * updating textures and data about textures from IPC and how textures are + * composited (tiling, double buffering, etc.). + * + * Update (for images/canvases) and UpdateThebes (for Thebes) are called during + * the layers transaction to update the Compositbale's textures from the + * content side. The actual update (and any syncronous upload) is done by the + * TextureHost, but it is coordinated by the CompositableHost. + * + * Composite is called by the owning layer when it is composited. + * CompositableHost will use its TextureHost(s) and call Compositor::DrawQuad to + * do the actual rendering. + */ +class CompositableHost { + protected: + virtual ~CompositableHost(); + + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableHost) + explicit CompositableHost(const TextureInfo& aTextureInfo); + + static already_AddRefed<CompositableHost> Create( + const TextureInfo& aTextureInfo, bool aUseWebRender); + + virtual CompositableType GetType() = 0; + + // If base class overrides, it should still call the parent implementation + virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider); + + // composite the contents of this buffer host to the compositor's surface + virtual void Composite(Compositor* aCompositor, LayerComposite* aLayer, + EffectChain& aEffectChain, float aOpacity, + const gfx::Matrix4x4& aTransform, + const gfx::SamplingFilter aSamplingFilter, + const gfx::IntRect& aClipRect, + const nsIntRegion* aVisibleRegion = nullptr, + const Maybe<gfx::Polygon>& aGeometry = Nothing()) = 0; + + /** + * Update the content host. + * aUpdated is the region which should be updated. + */ + virtual bool UpdateThebes(const ThebesBufferData& aData, + const nsIntRegion& aUpdated, + const nsIntRegion& aOldValidRegionBack) { + NS_ERROR("should be implemented or not used"); + return false; + } + + /** + * Returns the front buffer. + * *aPictureRect (if non-null, and the returned TextureHost is non-null) + * is set to the picture rect. + */ + virtual TextureHost* GetAsTextureHost(gfx::IntRect* aPictureRect = nullptr) { + return nullptr; + } + + virtual gfx::IntSize GetImageSize() { + MOZ_ASSERT(false, "Should have been overridden"); + return gfx::IntSize(); + } + + const TextureInfo& GetTextureInfo() const { return mTextureInfo; } + + /** + * Adds a mask effect using this texture as the mask, if possible. + * @return true if the effect was added, false otherwise. + */ + bool AddMaskEffect(EffectChain& aEffects, const gfx::Matrix4x4& aTransform); + + void RemoveMaskEffect(); + + TextureSourceProvider* GetTextureSourceProvider() const; + + Layer* GetLayer() const { return mLayer; } + void SetLayer(Layer* aLayer) { mLayer = aLayer; } + + virtual ContentHost* AsContentHost() { return nullptr; } + virtual ContentHostTexture* AsContentHostTexture() { return nullptr; } + virtual ImageHost* AsImageHost() { return nullptr; } + virtual TiledContentHost* AsTiledContentHost() { return nullptr; } + virtual WebRenderImageHost* AsWebRenderImageHost() { return nullptr; } + + typedef uint32_t AttachFlags; + static const AttachFlags NO_FLAGS = 0; + static const AttachFlags ALLOW_REATTACH = 1; + static const AttachFlags KEEP_ATTACHED = 2; + static const AttachFlags FORCE_DETACH = 2; + + virtual void Attach(Layer* aLayer, TextureSourceProvider* aProvider, + AttachFlags aFlags = NO_FLAGS) { + MOZ_ASSERT(aProvider); + NS_ASSERTION(aFlags & ALLOW_REATTACH || !mAttached, + "Re-attaching compositables must be explicitly authorised"); + SetTextureSourceProvider(aProvider); + SetLayer(aLayer); + mAttached = true; + mKeepAttached = aFlags & KEEP_ATTACHED; + } + // Detach this compositable host from its layer. + // If we are used for async video, then it is not safe to blindly detach since + // we might be re-attached to a different layer. aLayer is the layer which the + // caller expects us to be attached to, we will only detach if we are in fact + // attached to that layer. If we are part of a normal layer, then we will be + // detached in any case. if aLayer is null, then we will only detach if we are + // not async. + // Only force detach if the IPDL tree is being shutdown. + virtual void Detach(Layer* aLayer = nullptr, AttachFlags aFlags = NO_FLAGS) { + if (!mKeepAttached || aLayer == mLayer || aFlags & FORCE_DETACH) { + SetLayer(nullptr); + mAttached = false; + mKeepAttached = false; + } + } + bool IsAttached() { return mAttached; } + + virtual void Dump(std::stringstream& aStream, const char* aPrefix = "", + bool aDumpHtml = false) {} + static void DumpTextureHost(std::stringstream& aStream, + TextureHost* aTexture); + + virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() { + return nullptr; + } + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0; + + struct TimedTexture { + CompositableTextureHostRef mTexture; + TimeStamp mTimeStamp; + gfx::IntRect mPictureRect; + int32_t mFrameID; + int32_t mProducerID; + }; + virtual void UseTextureHost(const nsTArray<TimedTexture>& aTextures); + virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack, + TextureHost* aTextureOnWhite); + virtual void RemoveTextureHost(TextureHost* aTexture); + + // Called every time this is composited + void BumpFlashCounter() { + mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX + ? DIAGNOSTIC_FLASH_COUNTER_MAX + : mFlashCounter + 1; + } + + uint64_t GetCompositorBridgeID() const { return mCompositorBridgeID; } + + const AsyncCompositableRef& GetAsyncRef() const { return mAsyncRef; } + void SetAsyncRef(const AsyncCompositableRef& aRef) { mAsyncRef = aRef; } + + void SetCompositorBridgeID(uint64_t aID) { mCompositorBridgeID = aID; } + + virtual bool Lock() { return false; } + + virtual void Unlock() {} + + virtual already_AddRefed<TexturedEffect> GenEffect( + const gfx::SamplingFilter aSamplingFilter) { + return nullptr; + } + + /// Called when shutting down the layer tree. + /// This is a good place to clear all potential gpu resources before the + /// widget is is destroyed. + virtual void CleanupResources() {} + + virtual void BindTextureSource() {} + + virtual uint32_t GetDroppedFrames() { return 0; } + + protected: + HostLayerManager* GetLayerManager() const; + + protected: + TextureInfo mTextureInfo; + AsyncCompositableRef mAsyncRef; + uint64_t mCompositorBridgeID; + RefPtr<TextureSourceProvider> mTextureSourceProvider; + Layer* mLayer; + uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true. + bool mAttached; + bool mKeepAttached; +}; + +class AutoLockCompositableHost final { + public: + explicit AutoLockCompositableHost(CompositableHost* aHost) : mHost(aHost) { + mSucceeded = (mHost && mHost->Lock()); + } + + ~AutoLockCompositableHost() { + if (mSucceeded && mHost) { + mHost->Unlock(); + } + } + + bool Failed() const { return !mSucceeded; } + + private: + RefPtr<CompositableHost> mHost; + bool mSucceeded; +}; + +} // namespace layers +} // namespace mozilla + +#endif |