summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/CanvasContext.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/webgpu/CanvasContext.cpp
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/webgpu/CanvasContext.cpp')
-rw-r--r--dom/webgpu/CanvasContext.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/dom/webgpu/CanvasContext.cpp b/dom/webgpu/CanvasContext.cpp
new file mode 100644
index 0000000000..a7a8b8ed9b
--- /dev/null
+++ b/dom/webgpu/CanvasContext.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "mozilla/dom/WebGPUBinding.h"
+#include "CanvasContext.h"
+#include "SwapChain.h"
+#include "nsDisplayList.h"
+#include "LayerUserData.h"
+#include "mozilla/dom/HTMLCanvasElement.h"
+#include "mozilla/layers/CompositorManagerChild.h"
+#include "mozilla/layers/RenderRootStateManager.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "ipc/WebGPUChild.h"
+
+namespace mozilla {
+namespace webgpu {
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(CanvasContext)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasContext)
+
+GPU_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasContext, mSwapChain,
+ mCanvasElement, mOffscreenCanvas)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CanvasContext)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+CanvasContext::CanvasContext()
+ : mExternalImageId(layers::CompositorManagerChild::GetInstance()
+ ->GetNextExternalImageId()) {}
+
+CanvasContext::~CanvasContext() {
+ Cleanup();
+ RemovePostRefreshObserver();
+}
+
+void CanvasContext::Cleanup() {
+ if (mSwapChain) {
+ mSwapChain->Destroy(mExternalImageId);
+ mSwapChain = nullptr;
+ }
+ if (mRenderRootStateManager && mImageKey) {
+ mRenderRootStateManager->AddImageKeyForDiscard(mImageKey.value());
+ mRenderRootStateManager = nullptr;
+ mImageKey.reset();
+ }
+}
+
+JSObject* CanvasContext::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return dom::GPUCanvasContext_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+already_AddRefed<layers::Layer> CanvasContext::GetCanvasLayer(
+ nsDisplayListBuilder* aBuilder, layers::Layer* aOldLayer,
+ layers::LayerManager* aManager) {
+ return nullptr;
+}
+
+bool CanvasContext::UpdateWebRenderCanvasData(
+ nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) {
+ return true;
+}
+
+RefPtr<SwapChain> CanvasContext::ConfigureSwapChain(
+ const dom::GPUSwapChainDescriptor& aDesc, ErrorResult& aRv) {
+ Cleanup();
+
+ gfx::SurfaceFormat format;
+ switch (aDesc.mFormat) {
+ case dom::GPUTextureFormat::Rgba8unorm:
+ format = gfx::SurfaceFormat::R8G8B8A8;
+ break;
+ case dom::GPUTextureFormat::Bgra8unorm:
+ format = gfx::SurfaceFormat::B8G8R8A8;
+ break;
+ default:
+ aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+ return nullptr;
+ }
+
+ dom::GPUExtent3DDict extent;
+ extent.mWidth = mWidth;
+ extent.mHeight = mHeight;
+ extent.mDepth = 1;
+ mSwapChain = new SwapChain(aDesc, extent, mExternalImageId, format);
+
+ // Force a new frame to be built, which will execute the
+ // `CanvasContextType::WebGPU` switch case in `CreateWebRenderCommands` and
+ // populate the WR user data.
+ mCanvasElement->InvalidateCanvas();
+
+ mSwapChain->GetCurrentTexture()->mTargetCanvasElement = mCanvasElement;
+ return mSwapChain;
+}
+
+Maybe<wr::ImageKey> CanvasContext::GetImageKey() const { return mImageKey; }
+
+wr::ImageKey CanvasContext::CreateImageKey(
+ layers::RenderRootStateManager* aManager) {
+ const auto key = aManager->WrBridge()->GetNextImageKey();
+ mRenderRootStateManager = aManager;
+ mImageKey = Some(key);
+ return key;
+}
+
+bool CanvasContext::UpdateWebRenderLocalCanvasData(
+ layers::WebRenderLocalCanvasData* aCanvasData) {
+ if (!mSwapChain || !mSwapChain->GetGpuBridge()) {
+ return false;
+ }
+
+ aCanvasData->mGpuBridge = mSwapChain->GetGpuBridge();
+ aCanvasData->mGpuTextureId = mSwapChain->GetCurrentTexture()->mId;
+ aCanvasData->mExternalImageId = mExternalImageId;
+ aCanvasData->mFormat = mSwapChain->mFormat;
+ return true;
+}
+
+} // namespace webgpu
+} // namespace mozilla