diff --git a/gfx/layers/composite/GPUVideoTextureHost.cpp b/gfx/layers/composite/GPUVideoTextureHost.cpp index 7a1e776b27dd..880c18ae4c10 100644 --- a/gfx/layers/composite/GPUVideoTextureHost.cpp +++ b/gfx/layers/composite/GPUVideoTextureHost.cpp @@ -216,6 +216,13 @@ BufferTextureHost* GPUVideoTextureHost::AsBufferTextureHost() { return nullptr; } +DXGITextureHostD3D11* GPUVideoTextureHost::AsDXGITextureHostD3D11() { + if (EnsureWrappedTextureHost()) { + return EnsureWrappedTextureHost()->AsDXGITextureHostD3D11(); + } + return nullptr; +} + bool GPUVideoTextureHost::IsWrappingSurfaceTextureHost() { if (EnsureWrappedTextureHost()) { return EnsureWrappedTextureHost()->IsWrappingSurfaceTextureHost(); diff --git a/gfx/layers/composite/GPUVideoTextureHost.h b/gfx/layers/composite/GPUVideoTextureHost.h index 205ced66b425..b94b6ef66528 100644 --- a/gfx/layers/composite/GPUVideoTextureHost.h +++ b/gfx/layers/composite/GPUVideoTextureHost.h @@ -67,6 +67,8 @@ class GPUVideoTextureHost : public TextureHost { BufferTextureHost* AsBufferTextureHost() override; + DXGITextureHostD3D11* AsDXGITextureHostD3D11() override; + bool IsWrappingSurfaceTextureHost() override; TextureHostType GetTextureHostType() override; diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 50aeb18402f8..f9747c2f4ff6 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -670,6 +670,9 @@ class TextureHost : public AtomicRefCountedWithFinalize { // Passed in the RenderCompositor supports BufferTextureHosts // being used directly as external compositor surfaces. SUPPORTS_EXTERNAL_BUFFER_TEXTURES, + + // Passed if the caller wants to disable external compositing of TextureHost + EXTERNAL_COMPOSITING_DISABLED, }; using PushDisplayItemFlagSet = EnumSet; diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 51143db26b74..7585841d617d 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -1221,17 +1221,23 @@ void DXGITextureHostD3D11::PushDisplayItems( return; } + bool preferExternalCompositing = + SupportsExternalCompositing(aBuilder.GetBackendType()); + if (aFlags.contains(PushDisplayItemFlag::EXTERNAL_COMPOSITING_DISABLED)) { + MOZ_ASSERT(aBuilder.GetBackendType() != WebRenderBackend::SOFTWARE); + preferExternalCompositing = false; + } + switch (GetFormat()) { case gfx::SurfaceFormat::R8G8B8X8: case gfx::SurfaceFormat::R8G8B8A8: case gfx::SurfaceFormat::B8G8R8A8: case gfx::SurfaceFormat::B8G8R8X8: { MOZ_ASSERT(aImageKeys.length() == 1); - aBuilder.PushImage( - aBounds, aClip, true, false, aFilter, aImageKeys[0], - !(mFlags & TextureFlags::NON_PREMULTIPLIED), - wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, preferCompositorSurface, - SupportsExternalCompositing(aBuilder.GetBackendType())); + aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0], + !(mFlags & TextureFlags::NON_PREMULTIPLIED), + wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, + preferCompositorSurface, preferExternalCompositing); break; } case gfx::SurfaceFormat::P010: @@ -1249,7 +1255,7 @@ void DXGITextureHostD3D11::PushDisplayItems( : wr::ColorDepth::Color16, wr::ToWrYuvColorSpace(ToYUVColorSpace(mColorSpace)), wr::ToWrColorRange(mColorRange), aFilter, preferCompositorSurface, - SupportsExternalCompositing(aBuilder.GetBackendType())); + preferExternalCompositing); break; } default: { diff --git a/gfx/layers/d3d11/TextureHostWrapperD3D11.h b/gfx/layers/d3d11/TextureHostWrapperD3D11.h index afeb577f1333..db1171e08a50 100644 --- a/gfx/layers/d3d11/TextureHostWrapperD3D11.h +++ b/gfx/layers/d3d11/TextureHostWrapperD3D11.h @@ -142,6 +142,10 @@ class TextureHostWrapperD3D11 : public TextureHost { TextureHostWrapperD3D11* AsTextureHostWrapperD3D11() override { return this; } + DXGITextureHostD3D11* AsDXGITextureHostD3D11() override { + return mTextureHostD3D11; + } + void PostTask(); bool UpdateTextureData(); diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index aacc44418127..8ec0f12eb5e9 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -18,6 +18,7 @@ #include "mozilla/layers/SharedSurfacesParent.h" #include "mozilla/layers/WebRenderImageHost.h" #include "mozilla/layers/WebRenderTextureHost.h" +#include "mozilla/webrender/RenderTextureHost.h" #include "mozilla/webrender/RenderThread.h" #include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/webrender/WebRenderTypes.h" @@ -35,13 +36,15 @@ AsyncImagePipelineManager::ForwardingExternalImage::~ForwardingExternalImage() { } AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline( - wr::PipelineId aPipelineId, layers::WebRenderBackend aBackend) + wr::PipelineId aPipelineId, layers::WebRenderBackend aBackend, + WebRenderImageHost* aImageHost) : mInitialised(false), mIsChanged(false), mUseExternalImage(false), mRotation(wr::WrRotation::Degree0), mFilter(wr::ImageRendering::Auto), mMixBlendMode(wr::MixBlendMode::Normal), + mImageHost(aImageHost), mDLBuilder(aPipelineId, aBackend) {} AsyncImagePipelineManager::AsyncImagePipelineManager( @@ -168,9 +171,8 @@ void AsyncImagePipelineManager::AddAsyncImagePipeline( uint64_t id = wr::AsUint64(aPipelineId); MOZ_ASSERT(!mAsyncImagePipelines.Contains(id)); - auto holder = - MakeUnique(aPipelineId, mApi->GetBackendType()); - holder->mImageHost = aImageHost; + auto holder = MakeUnique( + aPipelineId, mApi->GetBackendType(), aImageHost); mAsyncImagePipelines.InsertOrUpdate(id, std::move(holder)); AddPipeline(aPipelineId, /* aWrBridge */ nullptr); } @@ -264,6 +266,23 @@ Maybe AsyncImagePipelineManager::UpdateImageKeys( // If we already had a texture and the format hasn't changed, better to reuse // the image keys than create new ones. auto backend = aSceneBuilderTxn.GetBackendType(); + + bool videoOverlayDisabled = false; + RefPtr usageInfo; + // video overlay of DXGITextureHostD3D11 may be disabled dynamically + const bool checkVideoOverlayDisabled = !!aTexture->AsDXGITextureHostD3D11(); + if (checkVideoOverlayDisabled) { + auto externalImageKey = wrTexture->GetExternalImageKey(); + usageInfo = wr::RenderThread::Get()->GetOrMergeUsageInfo( + externalImageKey, + aPipeline->mImageHost->GetRenderTextureHostUsageInfo()); + if (usageInfo) { + videoOverlayDisabled = usageInfo->VideoOverlayDisabled(); + aPipeline->mImageHost->SetRenderTextureHostUsageInfo(usageInfo); + } + } + MOZ_ASSERT_IF(aPipeline->mVideoOverlayDisabled, videoOverlayDisabled); + bool canUpdate = !!previousTexture && previousTexture->GetTextureHostType() == aTexture->GetTextureHostType() && @@ -273,7 +292,13 @@ Maybe AsyncImagePipelineManager::UpdateImageKeys( previousTexture->NeedsYFlip() == aTexture->NeedsYFlip() && previousTexture->SupportsExternalCompositing(backend) == aTexture->SupportsExternalCompositing(backend) && - aPipeline->mKeys.Length() == numKeys; + aPipeline->mKeys.Length() == numKeys && + aPipeline->mVideoOverlayDisabled == videoOverlayDisabled; + + if (videoOverlayDisabled) { + MOZ_ASSERT(usageInfo); + aPipeline->mVideoOverlayDisabled = true; + } if (!canUpdate) { for (auto key : aPipeline->mKeys) { @@ -462,6 +487,12 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline( Range range_keys(&keys[0], keys.Length()); TextureHost::PushDisplayItemFlagSet flags; flags += TextureHost::PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE; + if (aPipeline->mVideoOverlayDisabled && + aPipeline->mDLBuilder.GetBackendType() != + WebRenderBackend::SOFTWARE) { + flags += + TextureHost::PushDisplayItemFlag::EXTERNAL_COMPOSITING_DISABLED; + } if (mApi->SupportsExternalBufferTextures()) { flags += TextureHost::PushDisplayItemFlag::SUPPORTS_EXTERNAL_BUFFER_TEXTURES; diff --git a/gfx/layers/wr/AsyncImagePipelineManager.h b/gfx/layers/wr/AsyncImagePipelineManager.h index f6c3b2a9606d..dbd8233f42a8 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.h +++ b/gfx/layers/wr/AsyncImagePipelineManager.h @@ -23,6 +23,7 @@ namespace mozilla { namespace wr { class DisplayListBuilder; +class RenderTextureHostUsageInfo; class WebRenderAPI; class WebRenderPipelineInfo; } // namespace wr @@ -196,7 +197,8 @@ class AsyncImagePipelineManager final { struct AsyncImagePipeline { AsyncImagePipeline(wr::PipelineId aPipelineId, - layers::WebRenderBackend aBackend); + layers::WebRenderBackend aBackend, + WebRenderImageHost* aImageHost); void Update(const LayoutDeviceRect& aScBounds, wr::WrRotation aRotation, const wr::ImageRendering& aFilter, const wr::MixBlendMode& aMixBlendMode) { @@ -216,10 +218,11 @@ class AsyncImagePipelineManager final { wr::WrRotation mRotation; wr::ImageRendering mFilter; wr::MixBlendMode mMixBlendMode; - RefPtr mImageHost; + const RefPtr mImageHost; CompositableTextureHostRef mCurrentTexture; nsTArray mKeys; wr::DisplayListBuilder mDLBuilder; + bool mVideoOverlayDisabled = false; }; void ApplyAsyncImageForPipeline(const wr::Epoch& aEpoch, diff --git a/gfx/layers/wr/WebRenderImageHost.h b/gfx/layers/wr/WebRenderImageHost.h index df7921f47fce..171c1abc58d7 100644 --- a/gfx/layers/wr/WebRenderImageHost.h +++ b/gfx/layers/wr/WebRenderImageHost.h @@ -13,6 +13,7 @@ #include "CompositableHost.h" // for CompositableHost #include "mozilla/layers/ImageComposite.h" // for ImageComposite #include "mozilla/WeakPtr.h" +#include "mozilla/webrender/RenderTextureHost.h" namespace mozilla { namespace layers { @@ -62,6 +63,14 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite { TextureHost* GetCurrentTextureHost() { return mCurrentTextureHost; } + void SetRenderTextureHostUsageInfo( + RefPtr aUsageInfo) { + mRenderTextureHostUsageInfo = aUsageInfo; + } + RefPtr GetRenderTextureHostUsageInfo() const { + return mRenderTextureHostUsageInfo; + } + protected: // ImageComposite TimeStamp GetCompositionTime() const override; @@ -81,6 +90,8 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite { bool mWaitingReadyCallback = false; bool mWaitForRemoteTextureOwner = true; + RefPtr mRenderTextureHostUsageInfo; + #if XP_WIN RefPtr mTextureAllocator; #endif diff --git a/gfx/layers/wr/WebRenderTextureHost.h b/gfx/layers/wr/WebRenderTextureHost.h index 5588d3485ee9..680c23d28b30 100644 --- a/gfx/layers/wr/WebRenderTextureHost.h +++ b/gfx/layers/wr/WebRenderTextureHost.h @@ -68,6 +68,10 @@ class WebRenderTextureHost : public TextureHost { return mWrappedTextureHost->AsBufferTextureHost(); } + DXGITextureHostD3D11* AsDXGITextureHostD3D11() override { + return mWrappedTextureHost->AsDXGITextureHostD3D11(); + } + bool IsWrappingSurfaceTextureHost() override; virtual void PrepareForUse() override; diff --git a/gfx/webrender_bindings/DCLayerTree.cpp b/gfx/webrender_bindings/DCLayerTree.cpp index cb5e85ab4f0a..693021c32a5b 100644 --- a/gfx/webrender_bindings/DCLayerTree.cpp +++ b/gfx/webrender_bindings/DCLayerTree.cpp @@ -674,15 +674,24 @@ void DCLayerTree::CompositorEndFrame() { return; } + for (auto it = mDCSurfaces.begin(); it != mDCSurfaces.end(); it++) { + auto* surfaceVideo = it->second->AsDCSurfaceVideo(); + if (surfaceVideo) { + surfaceVideo->DisableVideoOverlay(); + } + } + if (mUsedOverlayTypesInFrame & DCompOverlayTypes::SOFTWARE_DECODED_VIDEO) { gfxCriticalNoteOnce << "Sw video swapchain present is slow"; - RenderThread::Get()->NotifyWebRenderError( - wr::WebRenderError::VIDEO_SW_OVERLAY); + + nsPrintfCString marker("Sw video swapchain present is slow"); + PROFILER_MARKER_TEXT("DisableOverlay", GRAPHICS, {}, marker); } if (mUsedOverlayTypesInFrame & DCompOverlayTypes::HARDWARE_DECODED_VIDEO) { gfxCriticalNoteOnce << "Hw video swapchain present is slow"; - RenderThread::Get()->NotifyWebRenderError( - wr::WebRenderError::VIDEO_HW_OVERLAY); + + nsPrintfCString marker("Hw video swapchain present is slow"); + PROFILER_MARKER_TEXT("DisableOverlay", GRAPHICS, {}, marker); } } @@ -1353,10 +1362,14 @@ bool IsYUVSwapChainFormat(DXGI_FORMAT aFormat) { } void DCSurfaceVideo::AttachExternalImage(wr::ExternalImageId aExternalImage) { - RenderTextureHost* texture = - RenderThread::Get()->GetRenderTexture(aExternalImage); + auto [texture, usageInfo] = + RenderThread::Get()->GetRenderTextureAndUsageInfo(aExternalImage); MOZ_RELEASE_ASSERT(texture); + if (usageInfo) { + mRenderTextureHostUsageInfo = usageInfo; + } + if (mPrevTexture == texture) { return; } @@ -1618,15 +1631,24 @@ void DCSurfaceVideo::PresentVideo() { if (overlayType == DCompOverlayTypes::SOFTWARE_DECODED_VIDEO) { gfxCriticalNoteOnce << "Sw video swapchain present is slow"; - RenderThread::Get()->NotifyWebRenderError( - wr::WebRenderError::VIDEO_SW_OVERLAY); + + nsPrintfCString marker("Sw video swapchain present is slow"); + PROFILER_MARKER_TEXT("DisableOverlay", GRAPHICS, {}, marker); } else { gfxCriticalNoteOnce << "Hw video swapchain present is slow"; - RenderThread::Get()->NotifyWebRenderError( - wr::WebRenderError::VIDEO_HW_OVERLAY); + + nsPrintfCString marker("Hw video swapchain present is slow"); + PROFILER_MARKER_TEXT("DisableOverlay", GRAPHICS, {}, marker); } } +void DCSurfaceVideo::DisableVideoOverlay() { + if (!mRenderTextureHostUsageInfo) { + return; + } + mRenderTextureHostUsageInfo->DisableVideoOverlay(); +} + DXGI_FORMAT DCSurfaceVideo::GetSwapChainFormat(bool aUseVpAutoHDR) { if (aUseVpAutoHDR) { return DXGI_FORMAT_R16G16B16A16_FLOAT; diff --git a/gfx/webrender_bindings/DCLayerTree.h b/gfx/webrender_bindings/DCLayerTree.h index 242cd1ed494c..2709452e5f07 100644 --- a/gfx/webrender_bindings/DCLayerTree.h +++ b/gfx/webrender_bindings/DCLayerTree.h @@ -63,6 +63,7 @@ class DCSurface; class DCSurfaceVideo; class DCSurfaceHandle; class RenderTextureHost; +class RenderTextureHostUsageInfo; class RenderDcompSurfaceTextureHost; struct GpuOverlayInfo { @@ -394,6 +395,8 @@ class DCSurfaceVideo : public DCSurface { DCSurfaceVideo* AsDCSurfaceVideo() override { return this; } + void DisableVideoOverlay(); + protected: virtual ~DCSurfaceVideo(); @@ -414,6 +417,7 @@ class DCSurfaceVideo : public DCSurface { bool mFailedYuvSwapChain = false; RefPtr mRenderTextureHost; RefPtr mPrevTexture; + RefPtr mRenderTextureHostUsageInfo; int mSlowPresentCount = 0; bool mFirstPresent = true; const UINT mSwapChainBufferCount; diff --git a/gfx/webrender_bindings/RenderTextureHost.cpp b/gfx/webrender_bindings/RenderTextureHost.cpp index 71391bd1f79c..2972b820ea8d 100644 --- a/gfx/webrender_bindings/RenderTextureHost.cpp +++ b/gfx/webrender_bindings/RenderTextureHost.cpp @@ -7,6 +7,7 @@ #include "RenderTextureHost.h" #include "GLContext.h" +#include "mozilla/layers/CompositorThread.h" #include "RenderThread.h" namespace mozilla { @@ -54,5 +55,59 @@ void RenderTextureHost::Destroy() { MOZ_ASSERT_UNREACHABLE("unexpected to be called"); } +RefPtr RenderTextureHost::GetOrMergeUsageInfo( + const MutexAutoLock& aProofOfMapLock, + RefPtr aUsageInfo) { + MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread()); + + if (mRenderTextureHostUsageInfo && aUsageInfo) { + if (mRenderTextureHostUsageInfo == aUsageInfo) { + return mRenderTextureHostUsageInfo; + } + + // Merge 2 RenderTextureHostUsageInfos to one RenderTextureHostUsageInfo. + + const bool overlayDisabled = + mRenderTextureHostUsageInfo->VideoOverlayDisabled() || + aUsageInfo->VideoOverlayDisabled(); + + // If mRenderTextureHostUsageInfo and aUsageInfo are different objects, keep + // the older one. + RefPtr usageInfo = [&]() { + if (aUsageInfo->mCreationTimeStamp < + mRenderTextureHostUsageInfo->mCreationTimeStamp) { + return aUsageInfo; + } + return mRenderTextureHostUsageInfo; + }(); + + // Merge info. + if (overlayDisabled) { + usageInfo->DisableVideoOverlay(); + } + mRenderTextureHostUsageInfo = usageInfo; + } else if (aUsageInfo && !mRenderTextureHostUsageInfo) { + mRenderTextureHostUsageInfo = aUsageInfo; + } + + if (!mRenderTextureHostUsageInfo) { + MOZ_ASSERT(!aUsageInfo); + mRenderTextureHostUsageInfo = new RenderTextureHostUsageInfo; + } + + MOZ_ASSERT(mRenderTextureHostUsageInfo); + MOZ_ASSERT_IF(aUsageInfo && aUsageInfo->VideoOverlayDisabled(), + mRenderTextureHostUsageInfo->VideoOverlayDisabled()); + + return mRenderTextureHostUsageInfo; +} + +RefPtr RenderTextureHost::GetTextureHostUsageInfo( + const MutexAutoLock& aProofOfMapLock) { + MOZ_ASSERT(RenderThread::IsInRenderThread()); + + return mRenderTextureHostUsageInfo; +} + } // namespace wr } // namespace mozilla diff --git a/gfx/webrender_bindings/RenderTextureHost.h b/gfx/webrender_bindings/RenderTextureHost.h index 707d8edeb6a1..09f4991e65fe 100644 --- a/gfx/webrender_bindings/RenderTextureHost.h +++ b/gfx/webrender_bindings/RenderTextureHost.h @@ -10,6 +10,7 @@ #include "GLConsts.h" #include "GLTypes.h" #include "nsISupportsImpl.h" +#include "mozilla/Atomics.h" #include "mozilla/gfx/2D.h" #include "mozilla/layers/LayersSurfaces.h" #include "mozilla/RefPtr.h" @@ -43,6 +44,27 @@ class RenderTextureHostWrapper; void ActivateBindAndTexParameteri(gl::GLContext* aGL, GLenum aActiveTexture, GLenum aBindTarget, GLuint aBindTexture); +// RenderTextureHostUsageInfo holds information about how the RenderTextureHost +// is used. It is used by AsyncImagePipelineManager to determine how to render +// TextureHost. +class RenderTextureHostUsageInfo final { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHostUsageInfo) + + RenderTextureHostUsageInfo() : mCreationTimeStamp(TimeStamp::Now()) {} + + bool VideoOverlayDisabled() { return mVideoOverlayDisabled; } + void DisableVideoOverlay() { mVideoOverlayDisabled = true; } + + const TimeStamp mCreationTimeStamp; + + protected: + ~RenderTextureHostUsageInfo() = default; + + // RenderTextureHost prefers to disable video overlay. + Atomic mVideoOverlayDisabled{false}; +}; + class RenderTextureHost { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost) @@ -134,6 +156,16 @@ class RenderTextureHost { return false; } + // Get RenderTextureHostUsageInfo of the RenderTextureHost. + // If mRenderTextureHostUsageInfo and aUsageInfo are different, merge them to + // one RenderTextureHostUsageInfo. + virtual RefPtr GetOrMergeUsageInfo( + const MutexAutoLock& aProofOfMapLock, + RefPtr aUsageInfo); + + virtual RefPtr GetTextureHostUsageInfo( + const MutexAutoLock& aProofOfMapLock); + protected: virtual ~RenderTextureHost(); @@ -146,6 +178,9 @@ class RenderTextureHost { bool mIsFromDRMSource; + // protected by RenderThread::mRenderTextureMapLock + RefPtr mRenderTextureHostUsageInfo; + friend class RenderTextureHostWrapper; }; diff --git a/gfx/webrender_bindings/RenderTextureHostWrapper.cpp b/gfx/webrender_bindings/RenderTextureHostWrapper.cpp index 8a1efb0cbade..b44fd85722f8 100644 --- a/gfx/webrender_bindings/RenderTextureHostWrapper.cpp +++ b/gfx/webrender_bindings/RenderTextureHostWrapper.cpp @@ -181,6 +181,25 @@ bool RenderTextureHostWrapper::IsSoftwareDecodedVideo() { return mTextureHost->IsSoftwareDecodedVideo(); } +RefPtr +RenderTextureHostWrapper::GetOrMergeUsageInfo( + const MutexAutoLock& aProofOfMapLock, + RefPtr aUsageInfo) { + if (!mTextureHost) { + return nullptr; + } + return mTextureHost->GetOrMergeUsageInfo(aProofOfMapLock, aUsageInfo); +} + +RefPtr +RenderTextureHostWrapper::GetTextureHostUsageInfo( + const MutexAutoLock& aProofOfMapLock) { + if (!mTextureHost) { + return nullptr; + } + return mTextureHost->GetTextureHostUsageInfo(aProofOfMapLock); +} + size_t RenderTextureHostWrapper::GetPlaneCount() const { if (RenderTextureHostSWGL* swglHost = EnsureRenderTextureHostSWGL()) { return swglHost->GetPlaneCount(); diff --git a/gfx/webrender_bindings/RenderTextureHostWrapper.h b/gfx/webrender_bindings/RenderTextureHostWrapper.h index 006ddeea4c43..7ed47b9a7c65 100644 --- a/gfx/webrender_bindings/RenderTextureHostWrapper.h +++ b/gfx/webrender_bindings/RenderTextureHostWrapper.h @@ -49,6 +49,11 @@ class RenderTextureHostWrapper final : public RenderTextureHostSWGL { RenderTextureHostSWGL* AsRenderTextureHostSWGL() override; void SetIsSoftwareDecodedVideo() override; bool IsSoftwareDecodedVideo() override; + RefPtr GetOrMergeUsageInfo( + const MutexAutoLock& aProofOfMapLock, + RefPtr aUsageInfo) override; + RefPtr GetTextureHostUsageInfo( + const MutexAutoLock& aProofOfMapLock) override; // RenderTextureHostSWGL size_t GetPlaneCount() const override; diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index f6ff301380cf..212ee63a6caf 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -1163,6 +1163,22 @@ void RenderThread::HandleRenderTextureOps() { } } +RefPtr RenderThread::GetOrMergeUsageInfo( + const wr::ExternalImageId& aExternalImageId, + RefPtr aUsageInfo) { + MutexAutoLock lock(mRenderTextureMapLock); + if (mHasShutdown) { + return nullptr; + } + auto it = mRenderTextures.find(aExternalImageId); + if (it == mRenderTextures.end()) { + return nullptr; + } + + auto& texture = it->second; + return texture->GetOrMergeUsageInfo(lock, aUsageInfo); +} + void RenderThread::UnregisterExternalImageDuringShutdown( const wr::ExternalImageId& aExternalImageId) { MOZ_ASSERT(IsInRenderThread()); @@ -1193,6 +1209,18 @@ RenderTextureHost* RenderThread::GetRenderTexture( return it->second; } +std::tuple> +RenderThread::GetRenderTextureAndUsageInfo( + const wr::ExternalImageId& aExternalImageId) { + MutexAutoLock lock(mRenderTextureMapLock); + auto it = mRenderTextures.find(aExternalImageId); + MOZ_ASSERT(it != mRenderTextures.end()); + if (it == mRenderTextures.end()) { + return {}; + } + return {it->second, it->second->GetTextureHostUsageInfo(lock)}; +} + void RenderThread::InitDeviceTask() { MOZ_ASSERT(IsInRenderThread()); MOZ_ASSERT(!mSingletonGL); diff --git a/gfx/webrender_bindings/RenderThread.h b/gfx/webrender_bindings/RenderThread.h index 35349da49793..59a8752c2307 100644 --- a/gfx/webrender_bindings/RenderThread.h +++ b/gfx/webrender_bindings/RenderThread.h @@ -45,6 +45,7 @@ typedef MozPromise MemoryReportPromise; class RendererOGL; class RenderTextureHost; +class RenderTextureHostUsageInfo; class RenderThread; /// A rayon thread pool that is shared by all WebRender instances within a @@ -231,6 +232,11 @@ class RenderThread final { void HandleRenderTextureOps(); + /// Can be called from any thread. + RefPtr GetOrMergeUsageInfo( + const wr::ExternalImageId& aExternalImageId, + RefPtr aUsageInfo); + /// Can only be called from the render thread. void UnregisterExternalImageDuringShutdown( const wr::ExternalImageId& aExternalImageId); @@ -239,6 +245,10 @@ class RenderThread final { RenderTextureHost* GetRenderTexture( const wr::ExternalImageId& aExternalImageId); + /// Can only be called from the render thread. + std::tuple> + GetRenderTextureAndUsageInfo(const wr::ExternalImageId& aExternalImageId); + /// Can be called from any thread. bool IsDestroyed(wr::WindowId aWindowId); /// Can be called from any thread.