From 44d3c382b8647058ccd97bf21d7f4b31e57a9b41 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 22 Feb 2024 04:28:44 +0000 Subject: [PATCH] Bug 1881194 - Send TexTypeForWebgl from CanvasChild to CanvasTranslator. r=sotaro ImageBridgeChild::GetSingleton returns null in the GPU process. This causes DrawTargetWebgl::CopyToSwapChain to use an incorrect texture type for WebGL canvases when in the GPU process. To work around this, determine the texture type for WebGL in the content process and send it to CanvasTranslator for later usage. Differential Revision: https://phabricator.services.mozilla.com/D202292 --- dom/canvas/DrawTargetWebgl.cpp | 12 ++++-------- dom/canvas/DrawTargetWebgl.h | 3 ++- gfx/layers/CanvasDrawEventRecorder.cpp | 3 ++- gfx/layers/CanvasDrawEventRecorder.h | 5 +++-- gfx/layers/client/TextureClient.cpp | 4 +++- gfx/layers/client/TextureRecorded.cpp | 5 +++-- gfx/layers/client/TextureRecorded.h | 3 ++- gfx/layers/ipc/CanvasChild.cpp | 13 +++++++------ gfx/layers/ipc/CanvasChild.h | 2 +- gfx/layers/ipc/CanvasTranslator.cpp | 11 +++++++---- gfx/layers/ipc/CanvasTranslator.h | 3 +++ gfx/layers/ipc/PCanvas.ipdl | 6 +++--- 12 files changed, 40 insertions(+), 30 deletions(-) diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp index 6055fa72e17f..23f86ea1513b 100644 --- a/dom/canvas/DrawTargetWebgl.cpp +++ b/dom/canvas/DrawTargetWebgl.cpp @@ -19,8 +19,6 @@ #include "mozilla/gfx/PathHelpers.h" #include "mozilla/gfx/PathSkia.h" #include "mozilla/gfx/Swizzle.h" -#include "mozilla/layers/CanvasRenderer.h" -#include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageDataSerializer.h" #include "mozilla/layers/RemoteTextureMap.h" #include "skia/include/core/SkPixmap.h" @@ -4724,7 +4722,8 @@ void DrawTargetWebgl::EndFrame() { } bool DrawTargetWebgl::CopyToSwapChain( - layers::RemoteTextureId aId, layers::RemoteTextureOwnerId aOwnerId, + layers::TextureType aTextureType, layers::RemoteTextureId aId, + layers::RemoteTextureOwnerId aOwnerId, layers::RemoteTextureOwnerClient* aOwnerClient) { if (!mWebglValid && !FlushFromSkia()) { return false; @@ -4739,11 +4738,8 @@ bool DrawTargetWebgl::CopyToSwapChain( StaticPrefs::gfx_canvas_accelerated_async_present(); options.remoteTextureId = aId; options.remoteTextureOwnerId = aOwnerId; - const RefPtr imageBridge = - layers::ImageBridgeChild::GetSingleton(); - auto texType = layers::TexTypeForWebgl(imageBridge); - return mSharedContext->mWebgl->CopyToSwapChain(mFramebuffer, texType, options, - aOwnerClient); + return mSharedContext->mWebgl->CopyToSwapChain(mFramebuffer, aTextureType, + options, aOwnerClient); } already_AddRefed DrawTargetWebgl::CreateSimilarDrawTarget( diff --git a/dom/canvas/DrawTargetWebgl.h b/dom/canvas/DrawTargetWebgl.h index 7bc1a83abb59..955ccaabf0f7 100644 --- a/dom/canvas/DrawTargetWebgl.h +++ b/dom/canvas/DrawTargetWebgl.h @@ -577,7 +577,8 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr { void* GetNativeSurface(NativeSurfaceType aType) override; bool CopyToSwapChain( - layers::RemoteTextureId aId, layers::RemoteTextureOwnerId aOwnerId, + layers::TextureType aTextureType, layers::RemoteTextureId aId, + layers::RemoteTextureOwnerId aOwnerId, layers::RemoteTextureOwnerClient* aOwnerClient = nullptr); void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); } diff --git a/gfx/layers/CanvasDrawEventRecorder.cpp b/gfx/layers/CanvasDrawEventRecorder.cpp index 62e6c9e4c665..af143bf5cbdb 100644 --- a/gfx/layers/CanvasDrawEventRecorder.cpp +++ b/gfx/layers/CanvasDrawEventRecorder.cpp @@ -53,6 +53,7 @@ CanvasDrawEventRecorder::CanvasDrawEventRecorder( CanvasDrawEventRecorder::~CanvasDrawEventRecorder() { MOZ_ASSERT(!mWorkerRef); } bool CanvasDrawEventRecorder::Init(TextureType aTextureType, + TextureType aWebglTextureType, gfx::BackendType aBackendType, UniquePtr aHelpers) { NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder); @@ -104,7 +105,7 @@ bool CanvasDrawEventRecorder::Init(TextureType aTextureType, return false; } - if (!mHelpers->InitTranslator(aTextureType, aBackendType, + if (!mHelpers->InitTranslator(aTextureType, aWebglTextureType, aBackendType, std::move(header->handle), std::move(bufferHandles), mDefaultBufferSize, std::move(readerSem), std::move(writerSem))) { diff --git a/gfx/layers/CanvasDrawEventRecorder.h b/gfx/layers/CanvasDrawEventRecorder.h index 56b52381eead..c9eacf27acfd 100644 --- a/gfx/layers/CanvasDrawEventRecorder.h +++ b/gfx/layers/CanvasDrawEventRecorder.h @@ -73,6 +73,7 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate, virtual ~Helpers() = default; virtual bool InitTranslator(TextureType aTextureType, + TextureType aWebglTextureType, gfx::BackendType aBackendType, Handle&& aReadHandle, nsTArray&& aBufferHandles, @@ -94,8 +95,8 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate, virtual bool RestartReader() = 0; }; - bool Init(TextureType aTextureType, gfx::BackendType aBackendType, - UniquePtr aHelpers); + bool Init(TextureType aTextureType, TextureType aWebglTextureType, + gfx::BackendType aBackendType, UniquePtr aHelpers); /** * Record an event for processing by the CanvasParent's CanvasTranslator. diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index bfc20b9b0832..cf07a7dcf22c 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -27,6 +27,7 @@ #include "mozilla/gfx/gfxVars.h" #include "mozilla/ipc/CrossProcessSemaphore.h" #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc +#include "mozilla/layers/CanvasRenderer.h" #include "mozilla/layers/CompositableForwarder.h" #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/ImageBridgeChild.h" @@ -375,7 +376,8 @@ TextureData* TextureData::Create(TextureForwarder* aAllocator, RefPtr canvasChild = aAllocator->GetCanvasChild(); if (canvasChild) { return new RecordedTextureData(canvasChild.forget(), aSize, aFormat, - textureType); + textureType, + layers::TexTypeForWebgl(aKnowsCompositor)); } // If we must be remote, but there is no canvas child, then falling back // is not possible. diff --git a/gfx/layers/client/TextureRecorded.cpp b/gfx/layers/client/TextureRecorded.cpp index 7e7ee2da99b7..da4ca4f8f30e 100644 --- a/gfx/layers/client/TextureRecorded.cpp +++ b/gfx/layers/client/TextureRecorded.cpp @@ -23,9 +23,10 @@ static int64_t sNextRecordedTextureId = 0; RecordedTextureData::RecordedTextureData( already_AddRefed aCanvasChild, gfx::IntSize aSize, - gfx::SurfaceFormat aFormat, TextureType aTextureType) + gfx::SurfaceFormat aFormat, TextureType aTextureType, + TextureType aWebglTextureType) : mCanvasChild(aCanvasChild), mSize(aSize), mFormat(aFormat) { - mCanvasChild->EnsureRecorder(aSize, aFormat, aTextureType); + mCanvasChild->EnsureRecorder(aSize, aFormat, aTextureType, aWebglTextureType); } RecordedTextureData::~RecordedTextureData() { diff --git a/gfx/layers/client/TextureRecorded.h b/gfx/layers/client/TextureRecorded.h index d846c1fac188..56e504fb54f6 100644 --- a/gfx/layers/client/TextureRecorded.h +++ b/gfx/layers/client/TextureRecorded.h @@ -18,7 +18,8 @@ class RecordedTextureData final : public TextureData { public: RecordedTextureData(already_AddRefed aCanvasChild, gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - TextureType aTextureType); + TextureType aTextureType, + TextureType aWebglTextureType = TextureType::Unknown); void FillInfo(TextureData::Info& aInfo) const final; diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp index cb120c0385c8..bef28ef7a6c6 100644 --- a/gfx/layers/ipc/CanvasChild.cpp +++ b/gfx/layers/ipc/CanvasChild.cpp @@ -34,9 +34,9 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers { ~RecorderHelpers() override = default; - bool InitTranslator(TextureType aTextureType, gfx::BackendType aBackendType, - Handle&& aReadHandle, nsTArray&& aBufferHandles, - uint64_t aBufferSize, + bool InitTranslator(TextureType aTextureType, TextureType aWebglTextureType, + gfx::BackendType aBackendType, Handle&& aReadHandle, + nsTArray&& aBufferHandles, uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem, CrossProcessSemaphoreHandle&& aWriterSem) override { NS_ASSERT_OWNINGTHREAD(RecorderHelpers); @@ -44,7 +44,7 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers { return false; } return mCanvasChild->SendInitTranslator( - aTextureType, aBackendType, std::move(aReadHandle), + aTextureType, aWebglTextureType, aBackendType, std::move(aReadHandle), std::move(aBufferHandles), aBufferSize, std::move(aReaderSem), std::move(aWriterSem)); } @@ -209,14 +209,15 @@ ipc::IPCResult CanvasChild::RecvBlockCanvas() { } void CanvasChild::EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - TextureType aTextureType) { + TextureType aTextureType, + TextureType aWebglTextureType) { NS_ASSERT_OWNINGTHREAD(CanvasChild); if (!mRecorder) { gfx::BackendType backendType = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend(); auto recorder = MakeRefPtr(mWorkerRef); - if (!recorder->Init(aTextureType, backendType, + if (!recorder->Init(aTextureType, aWebglTextureType, backendType, MakeUnique(this))) { return; } diff --git a/gfx/layers/ipc/CanvasChild.h b/gfx/layers/ipc/CanvasChild.h index a3917c077322..0a288eb790a9 100644 --- a/gfx/layers/ipc/CanvasChild.h +++ b/gfx/layers/ipc/CanvasChild.h @@ -62,7 +62,7 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr { * @params aTextureType the TextureType to create in the CanvasTranslator. */ void EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - TextureType aTextureType); + TextureType aTextureType, TextureType aWebglTextureType); /** * Clean up IPDL actor. diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp index 320fa9a4194f..dbdad0d4ee08 100644 --- a/gfx/layers/ipc/CanvasTranslator.cpp +++ b/gfx/layers/ipc/CanvasTranslator.cpp @@ -132,15 +132,17 @@ bool CanvasTranslator::EnsureSharedContextWebgl() { } mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator( - TextureType aTextureType, gfx::BackendType aBackendType, - Handle&& aReadHandle, nsTArray&& aBufferHandles, - uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem, + TextureType aTextureType, TextureType aWebglTextureType, + gfx::BackendType aBackendType, Handle&& aReadHandle, + nsTArray&& aBufferHandles, uint64_t aBufferSize, + CrossProcessSemaphoreHandle&& aReaderSem, CrossProcessSemaphoreHandle&& aWriterSem) { if (mHeaderShmem) { return IPC_FAIL(this, "RecvInitTranslator called twice."); } mTextureType = aTextureType; + mWebglTextureType = aWebglTextureType; mBackendType = aBackendType; mOtherPid = OtherPid(); @@ -1040,7 +1042,8 @@ bool CanvasTranslator::PresentTexture(int64_t aTextureId, RemoteTextureId aId) { RemoteTextureOwnerId ownerId = info.mRemoteTextureOwnerId; if (gfx::DrawTargetWebgl* webgl = info.GetDrawTargetWebgl()) { EnsureRemoteTextureOwner(ownerId); - if (webgl->CopyToSwapChain(aId, ownerId, mRemoteTextureOwner)) { + if (webgl->CopyToSwapChain(mWebglTextureType, aId, ownerId, + mRemoteTextureOwner)) { return true; } if (mSharedContext && mSharedContext->IsContextLost()) { diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h index cf87b7ab53b4..5258e0c52955 100644 --- a/gfx/layers/ipc/CanvasTranslator.h +++ b/gfx/layers/ipc/CanvasTranslator.h @@ -69,6 +69,7 @@ class CanvasTranslator final : public gfx::InlineTranslator, * CanvasEventRingBuffer. * * @param aTextureType the TextureType the translator will create + * @param aWebglTextureType the TextureType of any WebGL buffers * @param aBackendType the BackendType for texture data * @param aHeaderHandle handle for the control header * @param aBufferHandles handles for the initial buffers for translation @@ -77,6 +78,7 @@ class CanvasTranslator final : public gfx::InlineTranslator, * @param aWriterSem writing blocked semaphore for the CanvasEventRingBuffer */ ipc::IPCResult RecvInitTranslator(TextureType aTextureType, + TextureType aWebglTextureType, gfx::BackendType aBackendType, Handle&& aReadHandle, nsTArray&& aBufferHandles, @@ -358,6 +360,7 @@ class CanvasTranslator final : public gfx::InlineTranslator, UniquePtr mWriterSemaphore; UniquePtr mReaderSemaphore; TextureType mTextureType = TextureType::Unknown; + TextureType mWebglTextureType = TextureType::Unknown; UniquePtr mReferenceTextureData; dom::ContentParentId mContentId; uint32_t mManagerId; diff --git a/gfx/layers/ipc/PCanvas.ipdl b/gfx/layers/ipc/PCanvas.ipdl index 5187e61d23a2..59896b72cfa0 100644 --- a/gfx/layers/ipc/PCanvas.ipdl +++ b/gfx/layers/ipc/PCanvas.ipdl @@ -32,9 +32,9 @@ parent: * each aBufferHandles' memory and the default size. aReaderSem and aWriterSem * are handles for the semaphores to handle waiting on either side. */ - async InitTranslator(TextureType aTextureType, BackendType aBackendType, - Handle aHeaderHandle, Handle[] aBufferHandles, - uint64_t aBufferSize, + async InitTranslator(TextureType aTextureType, TextureType aWebglTextureType, + BackendType aBackendType, Handle aHeaderHandle, + Handle[] aBufferHandles, uint64_t aBufferSize, CrossProcessSemaphoreHandle aReaderSem, CrossProcessSemaphoreHandle aWriterSem);