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/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<layers::ImageBridgeChild> 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<DrawTarget> DrawTargetWebgl::CreateSimilarDrawTarget(

View file

@ -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(); }

View file

@ -53,6 +53,7 @@ CanvasDrawEventRecorder::CanvasDrawEventRecorder(
CanvasDrawEventRecorder::~CanvasDrawEventRecorder() { MOZ_ASSERT(!mWorkerRef); }
bool CanvasDrawEventRecorder::Init(TextureType aTextureType,
TextureType aWebglTextureType,
gfx::BackendType aBackendType,
UniquePtr<Helpers> 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))) {

View file

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

View file

@ -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> 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.

View file

@ -23,9 +23,10 @@ static int64_t sNextRecordedTextureId = 0;
RecordedTextureData::RecordedTextureData(
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->EnsureRecorder(aSize, aFormat, aTextureType);
mCanvasChild->EnsureRecorder(aSize, aFormat, aTextureType, aWebglTextureType);
}
RecordedTextureData::~RecordedTextureData() {

View file

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

View file

@ -34,9 +34,9 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers {
~RecorderHelpers() override = default;
bool InitTranslator(TextureType aTextureType, gfx::BackendType aBackendType,
Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles,
uint64_t aBufferSize,
bool InitTranslator(TextureType aTextureType, TextureType aWebglTextureType,
gfx::BackendType aBackendType, Handle&& aReadHandle,
nsTArray<Handle>&& 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<CanvasDrawEventRecorder>(mWorkerRef);
if (!recorder->Init(aTextureType, backendType,
if (!recorder->Init(aTextureType, aWebglTextureType, backendType,
MakeUnique<RecorderHelpers>(this))) {
return;
}

View file

@ -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.

View file

@ -132,15 +132,17 @@ bool CanvasTranslator::EnsureSharedContextWebgl() {
}
mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
TextureType aTextureType, gfx::BackendType aBackendType,
Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles,
uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem,
TextureType aTextureType, TextureType aWebglTextureType,
gfx::BackendType aBackendType, Handle&& aReadHandle,
nsTArray<Handle>&& 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()) {

View file

@ -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<Handle>&& aBufferHandles,
@ -358,6 +360,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
TextureType mTextureType = TextureType::Unknown;
TextureType mWebglTextureType = TextureType::Unknown;
UniquePtr<TextureData> mReferenceTextureData;
dom::ContentParentId mContentId;
uint32_t mManagerId;

View file

@ -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);