Files
tubestation/gfx/ipc/CanvasManagerParent.h
Lee Salzman 1d18f4b2f5 Bug 1938053 - Accelerate canvas drawImage of a WebGL context. r=aosmond
Accelerated Canvas2D and WebGL both live within the GPU process and run within
the same thread. We want to avoid any kind of readbacks from the GPU process
to the content process when doing a drawImage of a WebGL context to an AC2D
canvas.

To achieve this, we pause the AC2D recording translation with an AwaitTranslationSync
event identified by a sync-id. Then we send a request over IPDL to snapshot the
WebGL context while this pause is ongoing via a SnapshotExternalCanvas IPDL message,
which uses the sync-id to identify the snapshot safely in a table of such external
snapshots and force translation to resume. Finally, we send a ResolveExternalSnapshot
event within the recording stream to lookup the snapshot based on the sync-id and
assign it an alias that can be used within the recording stream playback for drawImage.

The sync-id mechanism acts as a sequenced fence so that multiple SnapshotExternalCanvas
requests can be encountered simultaneously from IPDL without confusing the recording
playback.

Differential Revision: https://phabricator.services.mozilla.com/D243399
2025-04-15 16:44:20 +00:00

80 lines
2.6 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_gfx_ipc_CanvasManagerParent_h__
#define _include_gfx_ipc_CanvasManagerParent_h__
#include "mozilla/gfx/PCanvasManagerParent.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/StaticMonitor.h"
#include "mozilla/UniquePtr.h"
#include "nsHashtablesFwd.h"
#include "nsTArray.h"
namespace mozilla {
namespace layers {
class CanvasTranslator;
class HostIPCAllocator;
class SharedSurfacesHolder;
class SurfaceDescriptor;
} // namespace layers
namespace gfx {
class CanvasManagerParent final : public PCanvasManagerParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CanvasManagerParent, override);
static void Init(Endpoint<PCanvasManagerParent>&& aEndpoint,
layers::SharedSurfacesHolder* aSharedSurfacesHolder,
const dom::ContentParentId& aContentId);
static void Shutdown();
static void DisableRemoteCanvas();
CanvasManagerParent(layers::SharedSurfacesHolder* aSharedSurfacesHolder,
const dom::ContentParentId& aContentId);
void Bind(Endpoint<PCanvasManagerParent>&& aEndpoint);
void ActorDestroy(ActorDestroyReason aWhy) override;
already_AddRefed<dom::PWebGLParent> AllocPWebGLParent();
already_AddRefed<webgpu::PWebGPUParent> AllocPWebGPUParent();
already_AddRefed<layers::PCanvasParent> AllocPCanvasParent();
mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId);
mozilla::ipc::IPCResult RecvGetSnapshot(
const uint32_t& aManagerId, const int32_t& aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId,
webgl::FrontBufferSnapshotIpc* aResult);
static mozilla::ipc::IProtocol* GetCanvasActor(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId);
static already_AddRefed<DataSourceSurface> GetCanvasSurface(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId,
uintptr_t aSurfaceId);
private:
static void ShutdownInternal();
static void DisableRemoteCanvasInternal();
~CanvasManagerParent() override;
RefPtr<layers::SharedSurfacesHolder> mSharedSurfacesHolder;
const dom::ContentParentId mContentId;
uint32_t mId = 0;
using ManagerSet = nsTHashSet<RefPtr<CanvasManagerParent>>;
static ManagerSet sManagers;
};
} // namespace gfx
} // namespace mozilla
#endif // _include_gfx_ipc_CanvasManagerParent_h__