/* -*- 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 // for uint64_t #include // 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 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& 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 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& 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 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 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 mHost; bool mSucceeded; }; } // namespace layers } // namespace mozilla #endif