Skip to content

Commit

Permalink
Move DawnCallback from Blink to gpu/webgpu so it can be reused
Browse files Browse the repository at this point in the history
Also, rename it to WGPUCallback since it pertains to the WebGPU
C API which uses WGPU prefix, and does not contain any
Dawn-specific implementation details.

Bug: chromium:1315260
Change-Id: I09ff1d64a5c15614cf14b9a79b782cb8e2c30bdd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3641915
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1002449}
  • Loading branch information
austinEng authored and Chromium LUCI CQ committed May 12, 2022
1 parent 3a41e89 commit 1c6283f
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 56 deletions.
8 changes: 8 additions & 0 deletions gpu/webgpu/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright 2022 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

source_set("common") {
sources = [ "callback.h" ]
public_deps = [ "//base" ]
}
3 changes: 3 additions & 0 deletions gpu/webgpu/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cwallez@chromium.org
kainino@chromium.org
enga@chromium.org
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,42 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CALLBACK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CALLBACK_H_
#ifndef GPU_WEBGPU_CALLBACK_H_
#define GPU_WEBGPU_CALLBACK_H_

#include <memory>

#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "base/callback.h"

namespace blink {
namespace gpu::webgpu {

// DawnCallback<Callback> is a heap-allocated version of
// WGPUCallback<Callback> is a heap-allocated version of
// base::OnceCallback or base::RepeatingCallback.
// It is allocated on the heap so that it can be reinterpret_cast to/from
// void* and passed to Dawn C callbacks.
// void* and passed to WGPU C callbacks.
//
// Example:
// DawnOnceCallback<F>* callback =
// BindDawnOnceCallback(func, arg1);
// WGPUOnceCallback<F>* callback =
// BindWGPUOnceCallback(func, arg1);
//
// // |someDawnFunction| expects callback function with arguments:
// // |someWGPUFunction| expects callback function with arguments:
// // Args... args, void* userdata.
// // When it is called, it will forward to func(arg1, args...).
// GetProcs().someDawnFunction(
// GetProcs().someWGPUFunction(
// callback->UnboundCallback(), callback->AsUserdata());
template <typename Callback>
class DawnCallbackBase;
class WGPUCallbackBase;

template <typename Callback>
class DawnOnceCallback;
class WGPUOnceCallback;

template <typename Callback>
class DawnRepeatingCallback;
class WGPURepeatingCallback;

template <template <typename> class BaseCallbackTemplate,
typename R,
typename... Args>
class DawnCallbackBase<BaseCallbackTemplate<R(Args...)>> {
class WGPUCallbackBase<BaseCallbackTemplate<R(Args...)>> {
using BaseCallback = BaseCallbackTemplate<R(Args...)>;

static constexpr bool is_once_callback =
Expand All @@ -49,16 +49,16 @@ class DawnCallbackBase<BaseCallbackTemplate<R(Args...)>> {
"Callback must be base::OnceCallback or base::RepeatingCallback");

public:
explicit DawnCallbackBase(BaseCallback callback)
explicit WGPUCallbackBase(BaseCallback callback)
: callback_(std::move(callback)) {}

void* AsUserdata() { return static_cast<void*>(this); }

protected:
using UnboundCallbackFunction = R (*)(Args..., void*);

static DawnCallbackBase* FromUserdata(void* userdata) {
return static_cast<DawnCallbackBase*>(userdata);
static WGPUCallbackBase* FromUserdata(void* userdata) {
return static_cast<WGPUCallbackBase*>(userdata);
}

R Run(Args... args) && {
Expand All @@ -80,14 +80,14 @@ class DawnCallbackBase<BaseCallbackTemplate<R(Args...)>> {
};

template <typename R, typename... Args>
class DawnOnceCallback<R(Args...)>
: public DawnCallbackBase<base::OnceCallback<R(Args...)>> {
class WGPUOnceCallback<R(Args...)>
: public WGPUCallbackBase<base::OnceCallback<R(Args...)>> {
using BaseCallback = base::OnceCallback<R(Args...)>;

public:
using DawnCallbackBase<BaseCallback>::DawnCallbackBase;
using WGPUCallbackBase<BaseCallback>::WGPUCallbackBase;

typename DawnCallbackBase<BaseCallback>::UnboundCallbackFunction
typename WGPUCallbackBase<BaseCallback>::UnboundCallbackFunction
UnboundCallback() {
return CallUnboundOnceCallback;
}
Expand All @@ -96,58 +96,58 @@ class DawnOnceCallback<R(Args...)>
static R CallUnboundOnceCallback(Args... args, void* handle) {
// After this non-repeating callback is run, it should delete itself.
auto callback =
std::unique_ptr<DawnOnceCallback>(static_cast<DawnOnceCallback*>(
DawnCallbackBase<BaseCallback>::FromUserdata(handle)));
std::unique_ptr<WGPUOnceCallback>(static_cast<WGPUOnceCallback*>(
WGPUCallbackBase<BaseCallback>::FromUserdata(handle)));
return std::move(*callback).Run(std::forward<Args>(args)...);
}
};

template <typename R, typename... Args>
class DawnRepeatingCallback<R(Args...)>
: public DawnCallbackBase<base::RepeatingCallback<R(Args...)>> {
class WGPURepeatingCallback<R(Args...)>
: public WGPUCallbackBase<base::RepeatingCallback<R(Args...)>> {
using BaseCallback = base::RepeatingCallback<R(Args...)>;

public:
using DawnCallbackBase<BaseCallback>::DawnCallbackBase;
using WGPUCallbackBase<BaseCallback>::WGPUCallbackBase;

typename DawnCallbackBase<BaseCallback>::UnboundCallbackFunction
typename WGPUCallbackBase<BaseCallback>::UnboundCallbackFunction
UnboundCallback() {
return CallUnboundRepeatingCallback;
}

private:
static R CallUnboundRepeatingCallback(Args... args, void* handle) {
return static_cast<DawnRepeatingCallback*>(
DawnCallbackBase<BaseCallback>::FromUserdata(handle))
return static_cast<WGPURepeatingCallback*>(
WGPUCallbackBase<BaseCallback>::FromUserdata(handle))
->Run(std::forward<Args>(args)...);
}
};

template <typename FunctionType, typename... BoundParameters>
auto BindDawnOnceCallback(FunctionType&& function,
auto BindWGPUOnceCallback(FunctionType&& function,
BoundParameters&&... bound_parameters) {
static constexpr bool is_method =
base::internal::MakeFunctorTraits<FunctionType>::is_method;
static constexpr bool is_weak_method =
base::internal::IsWeakMethod<is_method, BoundParameters...>();
static_assert(!is_weak_method,
"BindDawnOnceCallback cannot be used with weak methods");
"BindWGPUOnceCallback cannot be used with weak methods");

auto cb = WTF::Bind(std::forward<FunctionType>(function),
std::forward<BoundParameters>(bound_parameters)...);
return new DawnOnceCallback<typename decltype(cb)::RunType>(std::move(cb));
auto cb = base::BindOnce(std::forward<FunctionType>(function),
std::forward<BoundParameters>(bound_parameters)...);
return new WGPUOnceCallback<typename decltype(cb)::RunType>(std::move(cb));
}

template <typename FunctionType, typename... BoundParameters>
auto BindDawnRepeatingCallback(FunctionType&& function,
auto BindWGPURepeatingCallback(FunctionType&& function,
BoundParameters&&... bound_parameters) {
auto cb =
WTF::BindRepeating(std::forward<FunctionType>(function),
std::forward<BoundParameters>(bound_parameters)...);
base::BindRepeating(std::forward<FunctionType>(function),
std::forward<BoundParameters>(bound_parameters)...);
return std::make_unique<
DawnRepeatingCallback<typename decltype(cb)::RunType>>(std::move(cb));
WGPURepeatingCallback<typename decltype(cb)::RunType>>(std::move(cb));
}

} // namespace blink
} // namespace gpu::webgpu

#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CALLBACK_H_
#endif // GPU_WEBGPU_CALLBACK_H_
4 changes: 2 additions & 2 deletions third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_queue.h"
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_callback.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
Expand Down Expand Up @@ -239,7 +239,7 @@ ScriptPromise GPUBuffer::MapAsyncImpl(ScriptState* script_state,

// And send the command, leaving remaining validation to Dawn.
auto* callback =
BindDawnOnceCallback(&GPUBuffer::OnMapAsyncCallback, WrapPersistent(this),
BindWGPUOnceCallback(&GPUBuffer::OnMapAsyncCallback, WrapPersistent(this),
WrapPersistent(resolver));

GetProcs().bufferMapAsync(GetHandle(), mode, map_offset, map_size,
Expand Down
12 changes: 6 additions & 6 deletions third_party/blink/renderer/modules/webgpu/gpu_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ GPUDevice::GPUDevice(ExecutionContext* execution_context,
this,
GetProcs().deviceGetQueue(GetHandle()))),
lost_property_(MakeGarbageCollected<LostProperty>(execution_context)),
error_callback_(BindDawnRepeatingCallback(&GPUDevice::OnUncapturedError,
error_callback_(BindWGPURepeatingCallback(&GPUDevice::OnUncapturedError,
WrapWeakPersistent(this))),
logging_callback_(BindDawnRepeatingCallback(&GPUDevice::OnLogging,
logging_callback_(BindWGPURepeatingCallback(&GPUDevice::OnLogging,
WrapWeakPersistent(this))),
// Note: This is a *repeating* callback even though we expect it to only
// be called once. This is because it may be called *zero* times.
// Because it might never be called, the GPUDevice needs to own the
// allocation so it can be appropriately freed on destruction. Thus, the
// callback should not be a OnceCallback which self-deletes after it is
// called.
lost_callback_(BindDawnRepeatingCallback(&GPUDevice::OnDeviceLostError,
lost_callback_(BindWGPURepeatingCallback(&GPUDevice::OnDeviceLostError,
WrapWeakPersistent(this))) {
DCHECK(dawn_device);
DCHECK(limits);
Expand Down Expand Up @@ -368,7 +368,7 @@ ScriptPromise GPUDevice::createRenderPipelineAsync(
resolver->Reject(exception_state);
} else {
auto* callback =
BindDawnOnceCallback(&GPUDevice::OnCreateRenderPipelineAsyncCallback,
BindWGPUOnceCallback(&GPUDevice::OnCreateRenderPipelineAsyncCallback,
WrapPersistent(this), WrapPersistent(resolver));
GetProcs().deviceCreateRenderPipelineAsync(
GetHandle(), &dawn_desc_info.dawn_desc, callback->UnboundCallback(),
Expand All @@ -393,7 +393,7 @@ ScriptPromise GPUDevice::createComputePipelineAsync(
AsDawnType(this, descriptor, &label, &computeStageDescriptor);

auto* callback =
BindDawnOnceCallback(&GPUDevice::OnCreateComputePipelineAsyncCallback,
BindWGPUOnceCallback(&GPUDevice::OnCreateComputePipelineAsyncCallback,
WrapPersistent(this), WrapPersistent(resolver));
GetProcs().deviceCreateComputePipelineAsync(GetHandle(), &dawn_desc,
callback->UnboundCallback(),
Expand Down Expand Up @@ -430,7 +430,7 @@ ScriptPromise GPUDevice::popErrorScope(ScriptState* script_state) {
ScriptPromise promise = resolver->Promise();

auto* callback =
BindDawnOnceCallback(&GPUDevice::OnPopErrorScopeCallback,
BindWGPUOnceCallback(&GPUDevice::OnPopErrorScopeCallback,
WrapPersistent(this), WrapPersistent(resolver));

GetProcs().devicePopErrorScope(GetHandle(), callback->UnboundCallback(),
Expand Down
8 changes: 4 additions & 4 deletions third_party/blink/renderer/modules/webgpu/gpu_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_callback.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"

namespace blink {
Expand Down Expand Up @@ -174,16 +174,16 @@ class GPUDevice final : public EventTargetWithInlineData,
Member<GPUSupportedLimits> limits_;
Member<GPUQueue> queue_;
Member<LostProperty> lost_property_;
std::unique_ptr<DawnRepeatingCallback<void(WGPUErrorType, const char*)>>
std::unique_ptr<WGPURepeatingCallback<void(WGPUErrorType, const char*)>>
error_callback_;
std::unique_ptr<DawnRepeatingCallback<void(WGPULoggingType, const char*)>>
std::unique_ptr<WGPURepeatingCallback<void(WGPULoggingType, const char*)>>
logging_callback_;
// lost_callback_ is stored as a unique_ptr since it may never be called.
// We need to be sure to free it on deletion of the device.
// Inside OnDeviceLostError we'll release the unique_ptr to avoid a double
// free.
std::unique_ptr<
DawnRepeatingCallback<void(WGPUDeviceLostReason, const char*)>>
WGPURepeatingCallback<void(WGPUDeviceLostReason, const char*)>>
lost_callback_;

static constexpr int kMaxAllowedConsoleWarnings = 500;
Expand Down
2 changes: 1 addition & 1 deletion third_party/blink/renderer/modules/webgpu/gpu_queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ ScriptPromise GPUQueue::onSubmittedWorkDone(ScriptState* script_state) {
ScriptPromise promise = resolver->Promise();

auto* callback =
BindDawnOnceCallback(&GPUQueue::OnWorkDoneCallback, WrapPersistent(this),
BindWGPUOnceCallback(&GPUQueue::OnWorkDoneCallback, WrapPersistent(this),
WrapPersistent(resolver));

GetProcs().queueOnSubmittedWorkDone(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_callback.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h"

namespace blink {

Expand Down Expand Up @@ -106,7 +106,7 @@ ScriptPromise GPUShaderModule::compilationInfo(ScriptState* script_state) {
ScriptPromise promise = resolver->Promise();

auto* callback =
BindDawnOnceCallback(&GPUShaderModule::OnCompilationInfoCallback,
BindWGPUOnceCallback(&GPUShaderModule::OnCompilationInfoCallback,
WrapPersistent(this), WrapPersistent(resolver));

GetProcs().shaderModuleGetCompilationInfo(
Expand Down
3 changes: 2 additions & 1 deletion third_party/blink/renderer/platform/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,6 @@ component("platform") {
"graphics/filters/spot_light_source.h",
"graphics/generated_image.cc",
"graphics/generated_image.h",
"graphics/gpu/dawn_callback.h",
"graphics/gpu/dawn_control_client_holder.cc",
"graphics/gpu/dawn_control_client_holder.h",
"graphics/gpu/drawing_buffer.cc",
Expand All @@ -907,6 +906,7 @@ component("platform") {
"graphics/gpu/shared_gpu_context.h",
"graphics/gpu/webgl_image_conversion.cc",
"graphics/gpu/webgl_image_conversion.h",
"graphics/gpu/webgpu_callback.h",
"graphics/gpu/webgpu_mailbox_texture.cc",
"graphics/gpu/webgpu_mailbox_texture.h",
"graphics/gpu/webgpu_resource_provider_cache.cc",
Expand Down Expand Up @@ -1645,6 +1645,7 @@ component("platform") {
"//gin",
"//gpu:gpu",
"//gpu/command_buffer/client:webgpu_interface",
"//gpu/webgpu:common",
"//media",
"//media/capture:capture_switches",
"//media/capture/mojom:video_capture",
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/platform/graphics/gpu/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include_rules = [
"+gpu/command_buffer/common/shared_image_usage.h",
"+gpu/config/gpu_driver_bug_workaround_type.h",
"+gpu/config/gpu_feature_info.h",
"+gpu/webgpu/callback.h",
"+ui/gfx/gpu_fence.h",
"+ui/gl/gpu_preference.h",
]
22 changes: 22 additions & 0 deletions third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_CALLBACK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_CALLBACK_H_

#include "gpu/webgpu/callback.h"

namespace blink {

// Alias these into the blink namespace as the gpu namespace is typically
// disallowed from being used directly outside of
// blink/renderer/platform/graphics/gpu.
using gpu::webgpu::BindWGPUOnceCallback;
using gpu::webgpu::BindWGPURepeatingCallback;
using gpu::webgpu::WGPUOnceCallback;
using gpu::webgpu::WGPURepeatingCallback;

} // namespace blink

#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_CALLBACK_H_

0 comments on commit 1c6283f

Please sign in to comment.