Files
tubestation/dom/webgpu/CanvasContext.cpp
Molnar Sandor 447e9dd8f4 Backed out 3 changesets (bug 1765816, bug 1755704) for causing bp hybrid bustages. CLOSED TREE
Backed out changeset 505897037daf (bug 1765816)
Backed out changeset bc4e2999a2a7 (bug 1755704)
Backed out changeset 26b11a2833b0 (bug 1755704)
2022-04-22 18:03:57 +03:00

128 lines
4.0 KiB
C++

/* -*- 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 "nsDisplayList.h"
#include "LayerUserData.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/layers/CompositableInProcessManager.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/RenderRootStateManager.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_WEAK_PTR(CanvasContext, mTexture,
mBridge, 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() = default;
CanvasContext::~CanvasContext() {
Cleanup();
RemovePostRefreshObserver();
}
void CanvasContext::Cleanup() { Unconfigure(); }
JSObject* CanvasContext::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::GPUCanvasContext_Binding::Wrap(aCx, this, aGivenProto);
}
void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aDesc) {
Unconfigure();
// these formats are guaranteed by the spec
switch (aDesc.mFormat) {
case dom::GPUTextureFormat::Rgba8unorm:
case dom::GPUTextureFormat::Rgba8unorm_srgb:
mGfxFormat = gfx::SurfaceFormat::R8G8B8A8;
break;
case dom::GPUTextureFormat::Bgra8unorm:
case dom::GPUTextureFormat::Bgra8unorm_srgb:
mGfxFormat = gfx::SurfaceFormat::B8G8R8A8;
break;
default:
NS_WARNING("Specified swap chain format is not supported");
return;
}
gfx::IntSize actualSize(mWidth, mHeight);
mHandle = layers::CompositableInProcessManager::GetNextHandle();
mTexture =
aDesc.mDevice->InitSwapChain(aDesc, mHandle, mGfxFormat, &actualSize);
mTexture->mTargetContext = this;
mBridge = aDesc.mDevice->GetBridge();
mGfxSize = actualSize;
// Force a new frame to be built, which will execute the
// `CanvasContextType::WebGPU` switch case in `CreateWebRenderCommands` and
// populate the WR user data.
if (mCanvasElement) {
mCanvasElement->InvalidateCanvas();
} else if (mOffscreenCanvas) {
dom::OffscreenCanvasDisplayData data;
data.mSize = {mWidth, mHeight};
data.mHandle = mHandle;
mOffscreenCanvas->UpdateDisplayData(data);
}
}
void CanvasContext::Unconfigure() {
if (mBridge && mBridge->IsOpen() && mHandle) {
mBridge->SendSwapChainDestroy(mHandle);
}
mHandle = layers::CompositableHandle();
mBridge = nullptr;
mTexture = nullptr;
mGfxFormat = gfx::SurfaceFormat::UNKNOWN;
}
dom::GPUTextureFormat CanvasContext::GetPreferredFormat(Adapter&) const {
return dom::GPUTextureFormat::Bgra8unorm;
}
RefPtr<Texture> CanvasContext::GetCurrentTexture(ErrorResult& aRv) {
if (!mTexture) {
aRv.ThrowOperationError("Canvas not configured");
return nullptr;
}
return mTexture;
}
void CanvasContext::MaybeQueueSwapChainPresent() {
if (mPendingSwapChainPresent) {
return;
}
mPendingSwapChainPresent = true;
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(
NewCancelableRunnableMethod("CanvasContext::SwapChainPresent", this,
&CanvasContext::SwapChainPresent)));
}
void CanvasContext::SwapChainPresent() {
mPendingSwapChainPresent = false;
if (mBridge && mBridge->IsOpen() && mHandle && mTexture) {
mBridge->SwapChainPresent(mHandle, mTexture->mId);
}
}
} // namespace webgpu
} // namespace mozilla