diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp index 972fa468d2e1..a97d553548e9 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.cpp +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -92,7 +92,9 @@ void OffscreenCanvasDisplayHelper::UpdateContext( OffscreenCanvas* aOffscreenCanvas, RefPtr&& aWorkerRef, CanvasContextType aType, const Maybe& aChildId) { RefPtr imageContainer = - MakeRefPtr(layers::ImageContainer::ASYNCHRONOUS); + MakeRefPtr( + layers::ImageUsageType::OffscreenCanvas, + layers::ImageContainer::ASYNCHRONOUS); MutexAutoLock lock(mMutex); diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 2db729fa2f68..a83458dbdab9 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -6278,7 +6278,8 @@ VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer() { } mVideoFrameContainer = new VideoFrameContainer( - this, MakeAndAddRef(ImageContainer::ASYNCHRONOUS)); + this, MakeAndAddRef(ImageUsageType::VideoFrameContainer, + ImageContainer::ASYNCHRONOUS)); return mVideoFrameContainer; } diff --git a/dom/media/VideoSegment.cpp b/dom/media/VideoSegment.cpp index 4f6ddff72919..a3dfa162d22f 100644 --- a/dom/media/VideoSegment.cpp +++ b/dom/media/VideoSegment.cpp @@ -44,8 +44,8 @@ void VideoFrame::TakeFrom(VideoFrame* aFrame) { /* static */ already_AddRefed VideoFrame::CreateBlackImage( const gfx::IntSize& aSize) { - RefPtr container = - MakeAndAddRef(ImageContainer::ASYNCHRONOUS); + RefPtr container = MakeAndAddRef( + ImageUsageType::BlackImage, ImageContainer::ASYNCHRONOUS); RefPtr image = container->CreatePlanarYCbCrImage(); if (!image) { return nullptr; diff --git a/dom/media/ipc/RemoteVideoDecoder.cpp b/dom/media/ipc/RemoteVideoDecoder.cpp index 8e4be480f0c4..421a1984e5a3 100644 --- a/dom/media/ipc/RemoteVideoDecoder.cpp +++ b/dom/media/ipc/RemoteVideoDecoder.cpp @@ -152,7 +152,9 @@ RemoteVideoDecoderParent::RemoteVideoDecoderParent( IPCResult RemoteVideoDecoderParent::RecvConstruct( ConstructResolver&& aResolver) { - auto imageContainer = MakeRefPtr(); + auto imageContainer = MakeRefPtr( + layers::ImageUsageType::RemoteVideoDecoder, + layers::ImageContainer::SYNCHRONOUS); if (mKnowsCompositor && XRE_IsRDDProcess()) { // Ensure to allocate recycle allocator imageContainer->EnsureRecycleAllocatorForRDD(mKnowsCompositor); diff --git a/dom/media/webcodecs/DecoderAgent.cpp b/dom/media/webcodecs/DecoderAgent.cpp index f7a539fa180c..2cc2ac0ad4ac 100644 --- a/dom/media/webcodecs/DecoderAgent.cpp +++ b/dom/media/webcodecs/DecoderAgent.cpp @@ -51,6 +51,7 @@ DecoderAgent::DecoderAgent(Id aId, UniquePtr&& aInfo) mOwnerThread(GetCurrentSerialEventTarget()), mPDMFactory(MakeRefPtr()), mImageContainer(MakeAndAddRef( + layers::ImageUsageType::WebCodecs, layers::ImageContainer::ASYNCHRONOUS)), mDecoder(nullptr), mState(State::Unconfigured) { diff --git a/dom/media/webrtc/MediaEngineFake.cpp b/dom/media/webrtc/MediaEngineFake.cpp index b14d80ffbbe4..6276cf6766dc 100644 --- a/dom/media/webrtc/MediaEngineFake.cpp +++ b/dom/media/webrtc/MediaEngineFake.cpp @@ -299,7 +299,7 @@ nsresult MediaEngineFakeVideoSource::Start() { if (!mImageContainer) { mImageContainer = MakeAndAddRef( - layers::ImageContainer::ASYNCHRONOUS); + layers::ImageUsageType::Webrtc, layers::ImageContainer::ASYNCHRONOUS); } // Start timer for subsequent frames diff --git a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp index dbb5e7ff7087..510763d1f434 100644 --- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp @@ -202,7 +202,7 @@ void MediaEngineRemoteVideoSource::SetTrack(const RefPtr& aTrack, if (!mImageContainer) { mImageContainer = MakeAndAddRef( - layers::ImageContainer::ASYNCHRONOUS); + layers::ImageUsageType::Webrtc, layers::ImageContainer::ASYNCHRONOUS); } { diff --git a/dom/media/webrtc/libwebrtcglue/WebrtcMediaDataDecoderCodec.cpp b/dom/media/webrtc/libwebrtcglue/WebrtcMediaDataDecoderCodec.cpp index bf35d4bcc545..f6dfa80eee62 100644 --- a/dom/media/webrtc/libwebrtcglue/WebrtcMediaDataDecoderCodec.cpp +++ b/dom/media/webrtc/libwebrtcglue/WebrtcMediaDataDecoderCodec.cpp @@ -20,6 +20,7 @@ WebrtcMediaDataDecoder::WebrtcMediaDataDecoder(nsACString& aCodecMimeType, mTaskQueue(TaskQueue::Create(do_AddRef(mThreadPool), "WebrtcMediaDataDecoder::mTaskQueue")), mImageContainer(MakeAndAddRef( + layers::ImageUsageType::Webrtc, layers::ImageContainer::ASYNCHRONOUS)), mFactory(new PDMFactory()), mTrackType(TrackInfo::kUndefinedTrack), diff --git a/dom/media/webrtc/transportbridge/MediaPipeline.cpp b/dom/media/webrtc/transportbridge/MediaPipeline.cpp index a5fe56f37fa2..6544cf68d766 100644 --- a/dom/media/webrtc/transportbridge/MediaPipeline.cpp +++ b/dom/media/webrtc/transportbridge/MediaPipeline.cpp @@ -1398,8 +1398,8 @@ class MediaPipelineReceiveVideo::PipelineListener PipelineListener(RefPtr aSource, TrackingId aTrackingId, PrincipalHandle aPrincipalHandle, PrincipalPrivacy aPrivacy) : GenericReceiveListener(std::move(aSource), std::move(aTrackingId)), - mImageContainer( - MakeAndAddRef(ImageContainer::ASYNCHRONOUS)), + mImageContainer(MakeAndAddRef( + ImageUsageType::Webrtc, ImageContainer::ASYNCHRONOUS)), mMutex("MediaPipelineReceiveVideo::PipelineListener::mMutex"), mPrincipalHandle(std::move(aPrincipalHandle)), mPrivacy(aPrivacy) {} diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index fe1695a2e5b4..3ffaee24d795 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -148,6 +148,20 @@ enum class CompositableType : uint8_t { COUNT }; +enum class ImageUsageType : uint8_t { + UNKNOWN, + WebRenderImageData, + WebRenderFallbackData, + Canvas, + OffscreenCanvas, + VideoFrameContainer, + RemoteVideoDecoder, + BlackImage, + Webrtc, + WebCodecs, + COUNT +}; + /** * Sent from the compositor to the content-side LayerManager, includes * properties of the compositor and should (in the future) include information @@ -223,15 +237,19 @@ struct TextureFactoryIdentifier { */ struct TextureInfo { CompositableType mCompositableType; + ImageUsageType mUsageType; TextureFlags mTextureFlags; TextureInfo() : mCompositableType(CompositableType::UNKNOWN), + mUsageType(ImageUsageType::UNKNOWN), mTextureFlags(TextureFlags::NO_FLAGS) {} - explicit TextureInfo(CompositableType aType, - TextureFlags aTextureFlags = TextureFlags::DEFAULT) - : mCompositableType(aType), mTextureFlags(aTextureFlags) {} + TextureInfo(CompositableType aType, ImageUsageType aUsageType, + TextureFlags aTextureFlags) + : mCompositableType(aType), + mUsageType(aUsageType), + mTextureFlags(aTextureFlags) {} bool operator==(const TextureInfo& aOther) const { return mCompositableType == aOther.mCompositableType && diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 56e7aad8b152..891f94fdf51e 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -163,30 +163,32 @@ void ImageContainer::EnsureImageClient() { } RefPtr imageBridge = ImageBridgeChild::GetSingleton(); - if (imageBridge) { - mImageClient = - imageBridge->CreateImageClient(CompositableType::IMAGE, this); - if (mImageClient) { - mAsyncContainerHandle = mImageClient->GetAsyncHandle(); - } else { - // It's okay to drop the async container handle since the ImageBridgeChild - // is going to die anyway. - mAsyncContainerHandle = CompositableHandle(); - } + if (!imageBridge) { + return; + } + + mImageClient = imageBridge->CreateImageClient(CompositableType::IMAGE, this); + if (mImageClient) { + mAsyncContainerHandle = mImageClient->GetAsyncHandle(); + } else { + // It's okay to drop the async container handle since the ImageBridgeChild + // is going to die anyway. + mAsyncContainerHandle = CompositableHandle(); } } -ImageContainer::ImageContainer(Mode flag) - : mRecursiveMutex("ImageContainer.mRecursiveMutex"), +ImageContainer::ImageContainer(ImageUsageType aUsageType, Mode aFlag) + : mUsageType(aUsageType), + mIsAsync(aFlag == ASYNCHRONOUS), + mRecursiveMutex("ImageContainer.mRecursiveMutex"), mGenerationCounter(++sGenerationCounter), mPaintCount(0), mDroppedImageCount(0), mImageFactory(new ImageFactory()), mRotation(VideoRotation::kDegree_0), mRecycleBin(new BufferRecycleBin()), - mIsAsync(flag == ASYNCHRONOUS), mCurrentProducerID(-1) { - if (flag == ASYNCHRONOUS) { + if (aFlag == ASYNCHRONOUS) { mNotifyCompositeListener = new ImageContainerListener(this); EnsureImageClient(); } @@ -350,6 +352,10 @@ void ImageContainer::ClearImagesFromImageBridge() { void ImageContainer::SetCurrentImages(const nsTArray& aImages) { AUTO_PROFILER_LABEL("ImageContainer::SetCurrentImages", GRAPHICS); MOZ_ASSERT(!aImages.IsEmpty()); + MOZ_ASSERT(mUsageType == ImageUsageType::Canvas || + mUsageType == ImageUsageType::OffscreenCanvas || + mUsageType == ImageUsageType::VideoFrameContainer); + RecursiveMutexAutoLock lock(mRecursiveMutex); if (mIsAsync) { if (RefPtr imageBridge = @@ -399,6 +405,9 @@ void ImageContainer::SetCurrentImageInTransaction(Image* aImage) { void ImageContainer::SetCurrentImagesInTransaction( const nsTArray& aImages) { + MOZ_ASSERT(!mIsAsync); + MOZ_ASSERT(mUsageType == ImageUsageType::WebRenderFallbackData); + NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); NS_ASSERTION(!HasImageClient(), "Should use async image transfer with ImageBridge."); diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h index 82f6efbd4ca2..6d78c1eea25c 100644 --- a/gfx/layers/ImageContainer.h +++ b/gfx/layers/ImageContainer.h @@ -324,7 +324,7 @@ class ImageContainer final : public SupportsThreadSafeWeakPtr { static const uint64_t sInvalidAsyncContainerId = 0; - explicit ImageContainer(ImageContainer::Mode flag = SYNCHRONOUS); + ImageContainer(ImageUsageType aUsageType, ImageContainer::Mode aFlag); ~ImageContainer(); @@ -579,6 +579,9 @@ class ImageContainer final : public SupportsThreadSafeWeakPtr { void DropImageClient(); + const ImageUsageType mUsageType; + const bool mIsAsync; + private: typedef mozilla::RecursiveMutex RecursiveMutex; @@ -655,7 +658,6 @@ class ImageContainer final : public SupportsThreadSafeWeakPtr { // than asynchronusly using the ImageBridge IPDL protocol. RefPtr mImageClient MOZ_GUARDED_BY(mRecursiveMutex); - const bool mIsAsync; CompositableHandle mAsyncContainerHandle MOZ_GUARDED_BY(mRecursiveMutex); // ProducerID for last current image(s) diff --git a/gfx/layers/client/CanvasClient.h b/gfx/layers/client/CanvasClient.h index 2136e6f65289..169213c05ab2 100644 --- a/gfx/layers/client/CanvasClient.h +++ b/gfx/layers/client/CanvasClient.h @@ -54,7 +54,8 @@ class CanvasClient final : public CompositableClient { } TextureInfo GetTextureInfo() const override { - return TextureInfo(CompositableType::IMAGE, mTextureFlags); + return TextureInfo(CompositableType::IMAGE, ImageUsageType::Canvas, + mTextureFlags); } void OnDetach() override { Clear(); } diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 85cfe90d168c..2ef2aa726e17 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -40,13 +40,13 @@ using namespace mozilla::gfx; /* static */ already_AddRefed ImageClient::CreateImageClient( - CompositableType aCompositableHostType, CompositableForwarder* aForwarder, - TextureFlags aFlags) { + CompositableType aCompositableHostType, ImageUsageType aUsageType, + CompositableForwarder* aForwarder, TextureFlags aFlags) { RefPtr result = nullptr; switch (aCompositableHostType) { case CompositableType::IMAGE: - result = - new ImageClientSingle(aForwarder, aFlags, CompositableType::IMAGE); + result = new ImageClientSingle(aForwarder, aFlags, + CompositableType::IMAGE, aUsageType); break; case CompositableType::UNKNOWN: result = nullptr; @@ -66,11 +66,13 @@ void ImageClient::RemoveTexture(TextureClient* aTexture) { ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd, TextureFlags aFlags, - CompositableType aType) - : ImageClient(aFwd, aFlags, aType) {} + CompositableType aType, + ImageUsageType aUsageType) + : ImageClient(aFwd, aFlags, aType, aUsageType) {} TextureInfo ImageClientSingle::GetTextureInfo() const { - return TextureInfo(CompositableType::IMAGE); + return TextureInfo(CompositableType::IMAGE, mUsageType, + TextureFlags::DEFAULT); } void ImageClientSingle::FlushAllImages() { @@ -270,9 +272,10 @@ bool ImageClientSingle::AddTextureClient(TextureClient* aTexture) { void ImageClientSingle::OnDetach() { mBuffers.Clear(); } ImageClient::ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags, - CompositableType aType) + CompositableType aType, ImageUsageType aUsageType) : CompositableClient(aFwd, aFlags), mType(aType), + mUsageType(aUsageType), mLastUpdateGenerationCounter(0) {} } // namespace layers diff --git a/gfx/layers/client/ImageClient.h b/gfx/layers/client/ImageClient.h index 899e40adffad..c50e3c1753b7 100644 --- a/gfx/layers/client/ImageClient.h +++ b/gfx/layers/client/ImageClient.h @@ -41,8 +41,8 @@ class ImageClient : public CompositableClient { * host. */ static already_AddRefed CreateImageClient( - CompositableType aImageHostType, CompositableForwarder* aFwd, - TextureFlags aFlags); + CompositableType aImageHostType, ImageUsageType aUsageType, + CompositableForwarder* aFwd, TextureFlags aFlags); virtual ~ImageClient() = default; @@ -72,11 +72,13 @@ class ImageClient : public CompositableClient { virtual RefPtr GetForwardedTexture() { return nullptr; } + CompositableType mType; + ImageUsageType mUsageType; + protected: ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags, - CompositableType aType); + CompositableType aType, ImageUsageType aUsageType); - CompositableType mType; uint32_t mLastUpdateGenerationCounter; }; @@ -86,7 +88,7 @@ class ImageClient : public CompositableClient { class ImageClientSingle : public ImageClient { public: ImageClientSingle(CompositableForwarder* aFwd, TextureFlags aFlags, - CompositableType aType); + CompositableType aType, ImageUsageType aUsageType); bool UpdateImage(ImageContainer* aContainer) override; diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 140d5680c5a7..d917dbc1dc62 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -100,9 +100,9 @@ class CompositableHost { virtual uint32_t GetDroppedFrames() { return 0; } + const TextureInfo mTextureInfo; + protected: - protected: - TextureInfo mTextureInfo; AsyncCompositableRef mAsyncRef; }; diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 32489afabd58..d7a77c320d15 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -681,8 +681,8 @@ RefPtr ImageBridgeChild::CreateImageClientNow( return nullptr; } - RefPtr client = - ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS); + RefPtr client = ImageClient::CreateImageClient( + aType, aImageContainer->mUsageType, this, TextureFlags::NO_FLAGS); MOZ_ASSERT(client, "failed to create ImageClient"); if (client) { client->Connect(aImageContainer); diff --git a/gfx/layers/ipc/LayersMessageUtils.h b/gfx/layers/ipc/LayersMessageUtils.h index a0da6154d538..7640e550df8a 100644 --- a/gfx/layers/ipc/LayersMessageUtils.h +++ b/gfx/layers/ipc/LayersMessageUtils.h @@ -668,11 +668,13 @@ struct ParamTraits { static void Write(MessageWriter* aWriter, const paramType& aParam) { WriteParam(aWriter, aParam.mCompositableType); + WriteParam(aWriter, aParam.mUsageType); WriteParam(aWriter, aParam.mTextureFlags); } static bool Read(MessageReader* aReader, paramType* aResult) { return ReadParam(aReader, &aResult->mCompositableType) && + ReadParam(aReader, &aResult->mUsageType) && ReadParam(aReader, &aResult->mTextureFlags); } }; @@ -684,6 +686,13 @@ struct ParamTraits mozilla::layers::CompositableType::UNKNOWN, mozilla::layers::CompositableType::COUNT> {}; +template <> +struct ParamTraits + : public ContiguousEnumSerializer { +}; + template <> struct ParamTraits { typedef mozilla::layers::ScrollableLayerGuid paramType; diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index d7c7468f5606..64f54d7768c7 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -2633,7 +2633,8 @@ WebRenderCommandBuilder::GenerateFallbackData( imageData->CreateImageClientIfNeeded(); RefPtr imageClient = imageData->GetImageClient(); - RefPtr imageContainer = MakeAndAddRef(); + RefPtr imageContainer = MakeAndAddRef( + ImageUsageType::WebRenderFallbackData, ImageContainer::SYNCHRONOUS); { UpdateImageHelper helper(imageContainer, imageClient, diff --git a/gfx/layers/wr/WebRenderUserData.cpp b/gfx/layers/wr/WebRenderUserData.cpp index cc8c18b7f6c6..a03c4526b898 100644 --- a/gfx/layers/wr/WebRenderUserData.cpp +++ b/gfx/layers/wr/WebRenderUserData.cpp @@ -235,7 +235,8 @@ void WebRenderImageData::CreateAsyncImageWebRenderCommands( void WebRenderImageData::CreateImageClientIfNeeded() { if (!mImageClient) { mImageClient = ImageClient::CreateImageClient( - CompositableType::IMAGE, WrBridge(), TextureFlags::DEFAULT); + CompositableType::IMAGE, ImageUsageType::WebRenderImageData, WrBridge(), + TextureFlags::DEFAULT); if (!mImageClient) { return; } @@ -399,7 +400,8 @@ void WebRenderCanvasData::SetImageContainer(ImageContainer* aImageContainer) { ImageContainer* WebRenderCanvasData::GetImageContainer() { if (!mContainer) { - mContainer = MakeAndAddRef(); + mContainer = MakeAndAddRef(ImageUsageType::Canvas, + ImageContainer::SYNCHRONOUS); } return mContainer; }