/* -*- 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 GFX_WEBRENDERUSERDATA_H #define GFX_WEBRENDERUSERDATA_H #include #include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/image/WebRenderImageProvider.h" #include "mozilla/layers/AnimationInfo.h" #include "mozilla/layers/LayersTypes.h" #include "mozilla/dom/RemoteBrowser.h" #include "mozilla/UniquePtr.h" #include "nsIFrame.h" #include "nsRefPtrHashtable.h" #include "nsTHashSet.h" #include "ImageTypes.h" #include "ImgDrawResult.h" #include "DisplayItemClip.h" namespace mozilla { class nsDisplayItemGeometry; namespace webgpu { class WebGPUChild; } namespace wr { class IpcResourceUpdateQueue; } namespace gfx { class SourceSurface; } namespace layers { class BasicLayerManager; class CanvasRenderer; class ImageClient; class ImageContainer; class WebRenderBridgeChild; class WebRenderCanvasData; class WebRenderCanvasRenderer; class WebRenderCanvasRendererAsync; class WebRenderImageData; class WebRenderImageProviderData; class WebRenderFallbackData; class RenderRootStateManager; class WebRenderGroupData; class WebRenderBackgroundData { public: WebRenderBackgroundData(wr::LayoutRect aBounds, wr::ColorF aColor) : mBounds(aBounds), mColor(aColor) {} void AddWebRenderCommands(wr::DisplayListBuilder& aBuilder); protected: wr::LayoutRect mBounds; wr::ColorF mColor; }; /// Parent class for arbitrary WebRender-specific data that can be associated /// to an nsFrame. class WebRenderUserData { public: typedef nsTHashSet> WebRenderUserDataRefTable; static bool SupportsAsyncUpdate(nsIFrame* aFrame); static bool ProcessInvalidateForImage(nsIFrame* aFrame, DisplayItemType aType, image::ImageProviderId aProviderId); NS_INLINE_DECL_REFCOUNTING(WebRenderUserData) WebRenderUserData(RenderRootStateManager* aManager, nsDisplayItem* aItem); WebRenderUserData(RenderRootStateManager* aManager, uint32_t mDisplayItemKey, nsIFrame* aFrame); virtual WebRenderImageData* AsImageData() { return nullptr; } virtual WebRenderImageProviderData* AsImageProviderData() { return nullptr; } virtual WebRenderFallbackData* AsFallbackData() { return nullptr; } virtual WebRenderCanvasData* AsCanvasData() { return nullptr; } virtual WebRenderGroupData* AsGroupData() { return nullptr; } enum class UserDataType { eImage, eFallback, eAPZAnimation, eAnimation, eCanvas, eRemote, eGroup, eMask, eImageProvider, // ImageLib eInProcessImage, }; virtual UserDataType GetType() = 0; bool IsUsed() { return mUsed; } void SetUsed(bool aUsed) { mUsed = aUsed; } nsIFrame* GetFrame() { return mFrame; } uint32_t GetDisplayItemKey() { return mDisplayItemKey; } void RemoveFromTable(); virtual nsDisplayItemGeometry* GetGeometry() { return nullptr; } protected: virtual ~WebRenderUserData(); WebRenderBridgeChild* WrBridge() const; RefPtr mManager; nsIFrame* mFrame; uint32_t mDisplayItemKey; WebRenderUserDataRefTable* mTable; bool mUsed; }; struct WebRenderUserDataKey { WebRenderUserDataKey(uint32_t aFrameKey, WebRenderUserData::UserDataType aType) : mFrameKey(aFrameKey), mType(aType) {} bool operator==(const WebRenderUserDataKey& other) const { return mFrameKey == other.mFrameKey && mType == other.mType; } PLDHashNumber Hash() const { return HashGeneric( mFrameKey, static_cast::type>(mType)); } uint32_t mFrameKey; WebRenderUserData::UserDataType mType; }; typedef nsRefPtrHashtable< nsGenericHashKey, WebRenderUserData> WebRenderUserDataTable; /// Holds some data used to share TextureClient/ImageClient with the parent /// process. class WebRenderImageData : public WebRenderUserData { public: WebRenderImageData(RenderRootStateManager* aManager, nsDisplayItem* aItem); WebRenderImageData(RenderRootStateManager* aManager, uint32_t aDisplayItemKey, nsIFrame* aFrame); virtual ~WebRenderImageData(); WebRenderImageData* AsImageData() override { return this; } UserDataType GetType() override { return UserDataType::eImage; } static UserDataType Type() { return UserDataType::eImage; } Maybe GetImageKey() { return mKey; } void SetImageKey(const wr::ImageKey& aKey); already_AddRefed GetImageClient(); Maybe UpdateImageKey(ImageContainer* aContainer, wr::IpcResourceUpdateQueue& aResources, bool aFallback = false); void CreateAsyncImageWebRenderCommands( mozilla::wr::DisplayListBuilder& aBuilder, ImageContainer* aContainer, const StackingContextHelper& aSc, const LayoutDeviceRect& aBounds, const LayoutDeviceRect& aSCBounds, VideoInfo::Rotation aRotation, const wr::ImageRendering& aFilter, const wr::MixBlendMode& aMixBlendMode, bool aIsBackfaceVisible); void CreateImageClientIfNeeded(); bool IsAsync() { return mPipelineId.isSome(); } void ClearImageKey(); protected: Maybe mKey; RefPtr mTextureOfImage; RefPtr mImageClient; Maybe mPipelineId; RefPtr mContainer; }; /// Holds some data used to share ImageLib results with the parent process. /// This may be either in the form of a blob recording or a rasterized surface. class WebRenderImageProviderData final : public WebRenderUserData { public: WebRenderImageProviderData(RenderRootStateManager* aManager, nsDisplayItem* aItem); WebRenderImageProviderData(RenderRootStateManager* aManager, uint32_t aDisplayItemKey, nsIFrame* aFrame); ~WebRenderImageProviderData() override; WebRenderImageProviderData* AsImageProviderData() override { return this; } UserDataType GetType() override { return UserDataType::eImageProvider; } static UserDataType Type() { return UserDataType::eImageProvider; } Maybe UpdateImageKey(image::WebRenderImageProvider* aProvider, image::ImgDrawResult aDrawResult, wr::IpcResourceUpdateQueue& aResources); bool Invalidate(image::ImageProviderId aProviderId) const; protected: RefPtr mProvider; Maybe mKey; image::ImgDrawResult mDrawResult = image::ImgDrawResult::NOT_READY; }; /// Used for fallback rendering. /// /// In most cases this uses blob images but it can also render on the content /// side directly into a texture. class WebRenderFallbackData : public WebRenderUserData { public: WebRenderFallbackData(RenderRootStateManager* aManager, nsDisplayItem* aItem); virtual ~WebRenderFallbackData(); WebRenderFallbackData* AsFallbackData() override { return this; } UserDataType GetType() override { return UserDataType::eFallback; } static UserDataType Type() { return UserDataType::eFallback; } nsDisplayItemGeometry* GetGeometry() override { return mGeometry.get(); } void SetInvalid(bool aInvalid) { mInvalid = aInvalid; } bool IsInvalid() { return mInvalid; } void SetFonts(const std::vector>& aFonts) { mFonts = aFonts; } Maybe GetBlobImageKey() { return mBlobKey; } void SetBlobImageKey(const wr::BlobImageKey& aKey); Maybe GetImageKey(); /// Create a WebRenderImageData to manage the image we are about to render /// into. WebRenderImageData* PaintIntoImage(); std::vector> mExternalSurfaces; UniquePtr mGeometry; DisplayItemClip mClip; nsRect mBounds; nsRect mBuildingRect; gfx::MatrixScales mScale; float mOpacity; protected: void ClearImageKey(); std::vector> mFonts; Maybe mBlobKey; // When rendering into a blob image, mImageData is null. It is non-null only // when we render directly into a texture on the content side. RefPtr mImageData; bool mInvalid; }; class WebRenderAPZAnimationData : public WebRenderUserData { public: WebRenderAPZAnimationData(RenderRootStateManager* aManager, nsDisplayItem* aItem); virtual ~WebRenderAPZAnimationData() = default; UserDataType GetType() override { return UserDataType::eAPZAnimation; } static UserDataType Type() { return UserDataType::eAPZAnimation; } uint64_t GetAnimationId() { return mAnimationId; } private: uint64_t mAnimationId; }; class WebRenderAnimationData : public WebRenderUserData { public: WebRenderAnimationData(RenderRootStateManager* aManager, nsDisplayItem* aItem); virtual ~WebRenderAnimationData(); UserDataType GetType() override { return UserDataType::eAnimation; } static UserDataType Type() { return UserDataType::eAnimation; } AnimationInfo& GetAnimationInfo() { return mAnimationInfo; } protected: AnimationInfo mAnimationInfo; }; class WebRenderCanvasData : public WebRenderUserData { public: WebRenderCanvasData(RenderRootStateManager* aManager, nsDisplayItem* aItem); virtual ~WebRenderCanvasData(); WebRenderCanvasData* AsCanvasData() override { return this; } UserDataType GetType() override { return UserDataType::eCanvas; } static UserDataType Type() { return UserDataType::eCanvas; } void ClearCanvasRenderer(); WebRenderCanvasRendererAsync* GetCanvasRenderer(); WebRenderCanvasRendererAsync* CreateCanvasRenderer(); bool SetCanvasRenderer(CanvasRenderer* aCanvasRenderer); void SetImageContainer(ImageContainer* aImageContainer); ImageContainer* GetImageContainer(); void ClearImageContainer(); protected: RefPtr mCanvasRenderer; RefPtr mContainer; }; class WebRenderRemoteData : public WebRenderUserData { public: WebRenderRemoteData(RenderRootStateManager* aManager, nsDisplayItem* aItem); virtual ~WebRenderRemoteData(); UserDataType GetType() override { return UserDataType::eRemote; } static UserDataType Type() { return UserDataType::eRemote; } void SetRemoteBrowser(dom::RemoteBrowser* aBrowser) { mRemoteBrowser = aBrowser; } protected: RefPtr mRemoteBrowser; }; class WebRenderMaskData : public WebRenderUserData { public: explicit WebRenderMaskData(RenderRootStateManager* aManager, nsDisplayItem* aItem) : WebRenderUserData(aManager, aItem), mMaskStyle(nsStyleImageLayers::LayerType::Mask), mShouldHandleOpacity(false) { MOZ_COUNT_CTOR(WebRenderMaskData); } virtual ~WebRenderMaskData() { MOZ_COUNT_DTOR(WebRenderMaskData); ClearImageKey(); } void ClearImageKey(); void Invalidate(); UserDataType GetType() override { return UserDataType::eMask; } static UserDataType Type() { return UserDataType::eMask; } Maybe mBlobKey; std::vector> mFonts; std::vector> mExternalSurfaces; LayerIntRect mItemRect; nsPoint mMaskOffset; nsStyleImageLayers mMaskStyle; gfx::MatrixScales mScale; bool mShouldHandleOpacity; }; extern void DestroyWebRenderUserDataTable(WebRenderUserDataTable* aTable); struct WebRenderUserDataProperty { NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(Key, WebRenderUserDataTable, DestroyWebRenderUserDataTable) }; template already_AddRefed GetWebRenderUserData(const nsIFrame* aFrame, uint32_t aPerFrameKey) { MOZ_ASSERT(aFrame); WebRenderUserDataTable* userDataTable = aFrame->GetProperty(WebRenderUserDataProperty::Key()); if (!userDataTable) { return nullptr; } WebRenderUserData* data = userDataTable->GetWeak(WebRenderUserDataKey(aPerFrameKey, T::Type())); if (data) { RefPtr result = static_cast(data); return result.forget(); } return nullptr; } } // namespace layers } // namespace mozilla #endif /* GFX_WEBRENDERUSERDATA_H */