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
This commit is contained in:
Lee Salzman 2024-02-22 04:28:44 +00:00
parent 54f446f3b5
commit 44d3c382b8
12 changed files with 40 additions and 30 deletions

View file

@ -19,8 +19,6 @@
#include "mozilla/gfx/PathHelpers.h" #include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/PathSkia.h" #include "mozilla/gfx/PathSkia.h"
#include "mozilla/gfx/Swizzle.h" #include "mozilla/gfx/Swizzle.h"
#include "mozilla/layers/CanvasRenderer.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/ImageDataSerializer.h" #include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/RemoteTextureMap.h" #include "mozilla/layers/RemoteTextureMap.h"
#include "skia/include/core/SkPixmap.h" #include "skia/include/core/SkPixmap.h"
@ -4724,7 +4722,8 @@ void DrawTargetWebgl::EndFrame() {
} }
bool DrawTargetWebgl::CopyToSwapChain( bool DrawTargetWebgl::CopyToSwapChain(
layers::RemoteTextureId aId, layers::RemoteTextureOwnerId aOwnerId, layers::TextureType aTextureType, layers::RemoteTextureId aId,
layers::RemoteTextureOwnerId aOwnerId,
layers::RemoteTextureOwnerClient* aOwnerClient) { layers::RemoteTextureOwnerClient* aOwnerClient) {
if (!mWebglValid && !FlushFromSkia()) { if (!mWebglValid && !FlushFromSkia()) {
return false; return false;
@ -4739,11 +4738,8 @@ bool DrawTargetWebgl::CopyToSwapChain(
StaticPrefs::gfx_canvas_accelerated_async_present(); StaticPrefs::gfx_canvas_accelerated_async_present();
options.remoteTextureId = aId; options.remoteTextureId = aId;
options.remoteTextureOwnerId = aOwnerId; options.remoteTextureOwnerId = aOwnerId;
const RefPtr<layers::ImageBridgeChild> imageBridge = return mSharedContext->mWebgl->CopyToSwapChain(mFramebuffer, aTextureType,
layers::ImageBridgeChild::GetSingleton(); options, aOwnerClient);
auto texType = layers::TexTypeForWebgl(imageBridge);
return mSharedContext->mWebgl->CopyToSwapChain(mFramebuffer, texType, options,
aOwnerClient);
} }
already_AddRefed<DrawTarget> DrawTargetWebgl::CreateSimilarDrawTarget( already_AddRefed<DrawTarget> DrawTargetWebgl::CreateSimilarDrawTarget(

View file

@ -577,7 +577,8 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
void* GetNativeSurface(NativeSurfaceType aType) override; void* GetNativeSurface(NativeSurfaceType aType) override;
bool CopyToSwapChain( bool CopyToSwapChain(
layers::RemoteTextureId aId, layers::RemoteTextureOwnerId aOwnerId, layers::TextureType aTextureType, layers::RemoteTextureId aId,
layers::RemoteTextureOwnerId aOwnerId,
layers::RemoteTextureOwnerClient* aOwnerClient = nullptr); layers::RemoteTextureOwnerClient* aOwnerClient = nullptr);
void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); } void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }

View file

@ -53,6 +53,7 @@ CanvasDrawEventRecorder::CanvasDrawEventRecorder(
CanvasDrawEventRecorder::~CanvasDrawEventRecorder() { MOZ_ASSERT(!mWorkerRef); } CanvasDrawEventRecorder::~CanvasDrawEventRecorder() { MOZ_ASSERT(!mWorkerRef); }
bool CanvasDrawEventRecorder::Init(TextureType aTextureType, bool CanvasDrawEventRecorder::Init(TextureType aTextureType,
TextureType aWebglTextureType,
gfx::BackendType aBackendType, gfx::BackendType aBackendType,
UniquePtr<Helpers> aHelpers) { UniquePtr<Helpers> aHelpers) {
NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder); NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder);
@ -104,7 +105,7 @@ bool CanvasDrawEventRecorder::Init(TextureType aTextureType,
return false; return false;
} }
if (!mHelpers->InitTranslator(aTextureType, aBackendType, if (!mHelpers->InitTranslator(aTextureType, aWebglTextureType, aBackendType,
std::move(header->handle), std::move(header->handle),
std::move(bufferHandles), mDefaultBufferSize, std::move(bufferHandles), mDefaultBufferSize,
std::move(readerSem), std::move(writerSem))) { std::move(readerSem), std::move(writerSem))) {

View file

@ -73,6 +73,7 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate,
virtual ~Helpers() = default; virtual ~Helpers() = default;
virtual bool InitTranslator(TextureType aTextureType, virtual bool InitTranslator(TextureType aTextureType,
TextureType aWebglTextureType,
gfx::BackendType aBackendType, gfx::BackendType aBackendType,
Handle&& aReadHandle, Handle&& aReadHandle,
nsTArray<Handle>&& aBufferHandles, nsTArray<Handle>&& aBufferHandles,
@ -94,8 +95,8 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate,
virtual bool RestartReader() = 0; virtual bool RestartReader() = 0;
}; };
bool Init(TextureType aTextureType, gfx::BackendType aBackendType, bool Init(TextureType aTextureType, TextureType aWebglTextureType,
UniquePtr<Helpers> aHelpers); gfx::BackendType aBackendType, UniquePtr<Helpers> aHelpers);
/** /**
* Record an event for processing by the CanvasParent's CanvasTranslator. * Record an event for processing by the CanvasParent's CanvasTranslator.

View file

@ -27,6 +27,7 @@
#include "mozilla/gfx/gfxVars.h" #include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/CrossProcessSemaphore.h" #include "mozilla/ipc/CrossProcessSemaphore.h"
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/CanvasRenderer.h"
#include "mozilla/layers/CompositableForwarder.h" #include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageBridgeChild.h"
@ -375,7 +376,8 @@ TextureData* TextureData::Create(TextureForwarder* aAllocator,
RefPtr<CanvasChild> canvasChild = aAllocator->GetCanvasChild(); RefPtr<CanvasChild> canvasChild = aAllocator->GetCanvasChild();
if (canvasChild) { if (canvasChild) {
return new RecordedTextureData(canvasChild.forget(), aSize, aFormat, 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 // If we must be remote, but there is no canvas child, then falling back
// is not possible. // is not possible.

View file

@ -23,9 +23,10 @@ static int64_t sNextRecordedTextureId = 0;
RecordedTextureData::RecordedTextureData( RecordedTextureData::RecordedTextureData(
already_AddRefed<CanvasChild> aCanvasChild, gfx::IntSize aSize, already_AddRefed<CanvasChild> aCanvasChild, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat, TextureType aTextureType) gfx::SurfaceFormat aFormat, TextureType aTextureType,
TextureType aWebglTextureType)
: mCanvasChild(aCanvasChild), mSize(aSize), mFormat(aFormat) { : mCanvasChild(aCanvasChild), mSize(aSize), mFormat(aFormat) {
mCanvasChild->EnsureRecorder(aSize, aFormat, aTextureType); mCanvasChild->EnsureRecorder(aSize, aFormat, aTextureType, aWebglTextureType);
} }
RecordedTextureData::~RecordedTextureData() { RecordedTextureData::~RecordedTextureData() {

View file

@ -18,7 +18,8 @@ class RecordedTextureData final : public TextureData {
public: public:
RecordedTextureData(already_AddRefed<CanvasChild> aCanvasChild, RecordedTextureData(already_AddRefed<CanvasChild> aCanvasChild,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureType aTextureType); TextureType aTextureType,
TextureType aWebglTextureType = TextureType::Unknown);
void FillInfo(TextureData::Info& aInfo) const final; void FillInfo(TextureData::Info& aInfo) const final;

View file

@ -34,9 +34,9 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers {
~RecorderHelpers() override = default; ~RecorderHelpers() override = default;
bool InitTranslator(TextureType aTextureType, gfx::BackendType aBackendType, bool InitTranslator(TextureType aTextureType, TextureType aWebglTextureType,
Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles, gfx::BackendType aBackendType, Handle&& aReadHandle,
uint64_t aBufferSize, nsTArray<Handle>&& aBufferHandles, uint64_t aBufferSize,
CrossProcessSemaphoreHandle&& aReaderSem, CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem) override { CrossProcessSemaphoreHandle&& aWriterSem) override {
NS_ASSERT_OWNINGTHREAD(RecorderHelpers); NS_ASSERT_OWNINGTHREAD(RecorderHelpers);
@ -44,7 +44,7 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers {
return false; return false;
} }
return mCanvasChild->SendInitTranslator( return mCanvasChild->SendInitTranslator(
aTextureType, aBackendType, std::move(aReadHandle), aTextureType, aWebglTextureType, aBackendType, std::move(aReadHandle),
std::move(aBufferHandles), aBufferSize, std::move(aReaderSem), std::move(aBufferHandles), aBufferSize, std::move(aReaderSem),
std::move(aWriterSem)); std::move(aWriterSem));
} }
@ -209,14 +209,15 @@ ipc::IPCResult CanvasChild::RecvBlockCanvas() {
} }
void CanvasChild::EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, void CanvasChild::EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureType aTextureType) { TextureType aTextureType,
TextureType aWebglTextureType) {
NS_ASSERT_OWNINGTHREAD(CanvasChild); NS_ASSERT_OWNINGTHREAD(CanvasChild);
if (!mRecorder) { if (!mRecorder) {
gfx::BackendType backendType = gfx::BackendType backendType =
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend(); gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
auto recorder = MakeRefPtr<CanvasDrawEventRecorder>(mWorkerRef); auto recorder = MakeRefPtr<CanvasDrawEventRecorder>(mWorkerRef);
if (!recorder->Init(aTextureType, backendType, if (!recorder->Init(aTextureType, aWebglTextureType, backendType,
MakeUnique<RecorderHelpers>(this))) { MakeUnique<RecorderHelpers>(this))) {
return; return;
} }

View file

@ -62,7 +62,7 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
* @params aTextureType the TextureType to create in the CanvasTranslator. * @params aTextureType the TextureType to create in the CanvasTranslator.
*/ */
void EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, void EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureType aTextureType); TextureType aTextureType, TextureType aWebglTextureType);
/** /**
* Clean up IPDL actor. * Clean up IPDL actor.

View file

@ -132,15 +132,17 @@ bool CanvasTranslator::EnsureSharedContextWebgl() {
} }
mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator( mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
TextureType aTextureType, gfx::BackendType aBackendType, TextureType aTextureType, TextureType aWebglTextureType,
Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles, gfx::BackendType aBackendType, Handle&& aReadHandle,
uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem, nsTArray<Handle>&& aBufferHandles, uint64_t aBufferSize,
CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem) { CrossProcessSemaphoreHandle&& aWriterSem) {
if (mHeaderShmem) { if (mHeaderShmem) {
return IPC_FAIL(this, "RecvInitTranslator called twice."); return IPC_FAIL(this, "RecvInitTranslator called twice.");
} }
mTextureType = aTextureType; mTextureType = aTextureType;
mWebglTextureType = aWebglTextureType;
mBackendType = aBackendType; mBackendType = aBackendType;
mOtherPid = OtherPid(); mOtherPid = OtherPid();
@ -1040,7 +1042,8 @@ bool CanvasTranslator::PresentTexture(int64_t aTextureId, RemoteTextureId aId) {
RemoteTextureOwnerId ownerId = info.mRemoteTextureOwnerId; RemoteTextureOwnerId ownerId = info.mRemoteTextureOwnerId;
if (gfx::DrawTargetWebgl* webgl = info.GetDrawTargetWebgl()) { if (gfx::DrawTargetWebgl* webgl = info.GetDrawTargetWebgl()) {
EnsureRemoteTextureOwner(ownerId); EnsureRemoteTextureOwner(ownerId);
if (webgl->CopyToSwapChain(aId, ownerId, mRemoteTextureOwner)) { if (webgl->CopyToSwapChain(mWebglTextureType, aId, ownerId,
mRemoteTextureOwner)) {
return true; return true;
} }
if (mSharedContext && mSharedContext->IsContextLost()) { if (mSharedContext && mSharedContext->IsContextLost()) {

View file

@ -69,6 +69,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* CanvasEventRingBuffer. * CanvasEventRingBuffer.
* *
* @param aTextureType the TextureType the translator will create * @param aTextureType the TextureType the translator will create
* @param aWebglTextureType the TextureType of any WebGL buffers
* @param aBackendType the BackendType for texture data * @param aBackendType the BackendType for texture data
* @param aHeaderHandle handle for the control header * @param aHeaderHandle handle for the control header
* @param aBufferHandles handles for the initial buffers for translation * @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 * @param aWriterSem writing blocked semaphore for the CanvasEventRingBuffer
*/ */
ipc::IPCResult RecvInitTranslator(TextureType aTextureType, ipc::IPCResult RecvInitTranslator(TextureType aTextureType,
TextureType aWebglTextureType,
gfx::BackendType aBackendType, gfx::BackendType aBackendType,
Handle&& aReadHandle, Handle&& aReadHandle,
nsTArray<Handle>&& aBufferHandles, nsTArray<Handle>&& aBufferHandles,
@ -358,6 +360,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
UniquePtr<CrossProcessSemaphore> mWriterSemaphore; UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
UniquePtr<CrossProcessSemaphore> mReaderSemaphore; UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
TextureType mTextureType = TextureType::Unknown; TextureType mTextureType = TextureType::Unknown;
TextureType mWebglTextureType = TextureType::Unknown;
UniquePtr<TextureData> mReferenceTextureData; UniquePtr<TextureData> mReferenceTextureData;
dom::ContentParentId mContentId; dom::ContentParentId mContentId;
uint32_t mManagerId; uint32_t mManagerId;

View file

@ -32,9 +32,9 @@ parent:
* each aBufferHandles' memory and the default size. aReaderSem and aWriterSem * each aBufferHandles' memory and the default size. aReaderSem and aWriterSem
* are handles for the semaphores to handle waiting on either side. * are handles for the semaphores to handle waiting on either side.
*/ */
async InitTranslator(TextureType aTextureType, BackendType aBackendType, async InitTranslator(TextureType aTextureType, TextureType aWebglTextureType,
Handle aHeaderHandle, Handle[] aBufferHandles, BackendType aBackendType, Handle aHeaderHandle,
uint64_t aBufferSize, Handle[] aBufferHandles, uint64_t aBufferSize,
CrossProcessSemaphoreHandle aReaderSem, CrossProcessSemaphoreHandle aReaderSem,
CrossProcessSemaphoreHandle aWriterSem); CrossProcessSemaphoreHandle aWriterSem);