Skip to content

Commit 97daff9

Browse files
andyleisersonpchevrel@mozilla.com
authored andcommitted
Bug 1972921 - Track canvas textures used in bind groups a=pascalc
Differential Revision: https://phabricator.services.mozilla.com/D256014
1 parent e3bd27c commit 97daff9

24 files changed

+667
-20
lines changed

dom/webgpu/BindGroup.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ namespace mozilla::webgpu {
1414
GPU_IMPL_CYCLE_COLLECTION(BindGroup, mParent)
1515
GPU_IMPL_JS_WRAP(BindGroup)
1616

17-
BindGroup::BindGroup(Device* const aParent, RawId aId)
18-
: ChildOf(aParent), mId(aId) {
17+
BindGroup::BindGroup(Device* const aParent, RawId aId,
18+
CanvasContextArray&& aCanvasContexts)
19+
: ChildOf(aParent),
20+
mId(aId),
21+
mUsedCanvasContexts(std::move(aCanvasContexts)) {
1922
MOZ_RELEASE_ASSERT(aId);
2023
}
2124

dom/webgpu/BindGroup.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define GPU_BindGroup_H_
88

99
#include "nsWrapperCache.h"
10+
#include "CanvasContext.h"
1011
#include "ObjectModel.h"
1112
#include "mozilla/webgpu/WebGPUTypes.h"
1213

@@ -19,13 +20,21 @@ class BindGroup final : public ObjectBase, public ChildOf<Device> {
1920
GPU_DECL_CYCLE_COLLECTION(BindGroup)
2021
GPU_DECL_JS_WRAP(BindGroup)
2122

22-
BindGroup(Device* const aParent, RawId aId);
23+
BindGroup(Device* const aParent, RawId aId,
24+
CanvasContextArray&& aCanvasContexts);
2325

2426
const RawId mId;
2527

28+
mozilla::Span<const WeakPtr<CanvasContext>> GetCanvasContexts() const {
29+
return mUsedCanvasContexts;
30+
}
31+
2632
private:
2733
~BindGroup();
2834
void Cleanup();
35+
36+
// The canvas contexts of any canvas textures used in this bind group.
37+
CanvasContextArray mUsedCanvasContexts;
2938
};
3039

3140
} // namespace mozilla::webgpu

dom/webgpu/CanvasContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
118118
bool mNewTextureRequested = false;
119119
};
120120

121+
typedef AutoTArray<WeakPtr<CanvasContext>, 1> CanvasContextArray;
122+
121123
} // namespace webgpu
122124
} // namespace mozilla
123125

dom/webgpu/CommandEncoder.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ void CommandEncoder::Cleanup() {
101101

102102
RefPtr<WebGPUChild> CommandEncoder::GetBridge() { return mBridge; }
103103

104-
void CommandEncoder::TrackPresentationContext(CanvasContext* aTargetContext) {
104+
void CommandEncoder::TrackPresentationContext(
105+
WeakPtr<CanvasContext> aTargetContext) {
105106
if (aTargetContext) {
106107
mPresentationContexts.AppendElement(aTargetContext);
107108
}
@@ -302,7 +303,8 @@ void CommandEncoder::ResolveQuerySet(QuerySet& aQuerySet, uint32_t aFirstQuery,
302303
mBridge->SendCommandEncoderAction(mId, mParent->mId, std::move(bb));
303304
}
304305

305-
void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass) {
306+
void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass,
307+
CanvasContextArray& aCanvasContexts) {
306308
// Because this can be called during child Cleanup, we need to check
307309
// that the bridge is still alive.
308310
if (!mBridge || !mBridge->CanSend()) {
@@ -316,12 +318,17 @@ void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass) {
316318
}
317319
mState = CommandEncoderState::Open;
318320

321+
for (const auto& context : aCanvasContexts) {
322+
TrackPresentationContext(context);
323+
}
324+
319325
ipc::ByteBuf byteBuf;
320326
ffi::wgpu_compute_pass_finish(&aPass, ToFFI(&byteBuf));
321327
mBridge->SendComputePass(mId, mParent->mId, std::move(byteBuf));
322328
}
323329

324-
void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass) {
330+
void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass,
331+
CanvasContextArray& aCanvasContexts) {
325332
// Because this can be called during child Cleanup, we need to check
326333
// that the bridge is still alive.
327334
if (!mBridge || !mBridge->CanSend()) {
@@ -335,6 +342,10 @@ void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass) {
335342
}
336343
mState = CommandEncoderState::Open;
337344

345+
for (const auto& context : aCanvasContexts) {
346+
TrackPresentationContext(context);
347+
}
348+
338349
ipc::ByteBuf byteBuf;
339350
ffi::wgpu_render_pass_finish(&aPass, ToFFI(&byteBuf));
340351
mBridge->SendRenderPass(mId, mParent->mId, std::move(byteBuf));

dom/webgpu/CommandEncoder.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mozilla/webgpu/ffi/wgpu.h"
1313
#include "mozilla/webgpu/WebGPUTypes.h"
1414
#include "nsWrapperCache.h"
15+
#include "CanvasContext.h"
1516
#include "ObjectModel.h"
1617
#include "QuerySet.h"
1718

@@ -68,18 +69,20 @@ class CommandEncoder final : public ObjectBase, public ChildOf<Device> {
6869
CommandEncoderState mState;
6970

7071
RefPtr<WebGPUChild> mBridge;
71-
nsTArray<WeakPtr<CanvasContext>> mPresentationContexts;
72+
CanvasContextArray mPresentationContexts;
7273

73-
void TrackPresentationContext(CanvasContext* aTargetContext);
74+
void TrackPresentationContext(WeakPtr<CanvasContext> aTargetContext);
7475

7576
public:
7677
const auto& GetDevice() const { return mParent; };
7778
RefPtr<WebGPUChild> GetBridge();
7879

7980
CommandEncoderState GetState() const { return mState; };
8081

81-
void EndComputePass(ffi::WGPURecordedComputePass& aPass);
82-
void EndRenderPass(ffi::WGPURecordedRenderPass& aPass);
82+
void EndComputePass(ffi::WGPURecordedComputePass& aPass,
83+
CanvasContextArray& aCanvasContexts);
84+
void EndRenderPass(ffi::WGPURecordedRenderPass& aPass,
85+
CanvasContextArray& aCanvasContexts);
8386

8487
void CopyBufferToBuffer(const Buffer& aSource, const Buffer& aDestination,
8588
const dom::Optional<BufferAddress>& aSize) {

dom/webgpu/ComputePassEncoder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void ComputePassEncoder::SetBindGroup(uint32_t aSlot,
6464
RawId bindGroup = 0;
6565
if (aBindGroup) {
6666
mUsedBindGroups.AppendElement(aBindGroup);
67+
mUsedCanvasContexts.AppendElements(aBindGroup->GetCanvasContexts());
6768
bindGroup = aBindGroup->mId;
6869
}
6970
ffi::wgpu_recorded_compute_pass_set_bind_group(
@@ -160,7 +161,7 @@ void ComputePassEncoder::End() {
160161
return;
161162
}
162163
MOZ_ASSERT(!!mPass);
163-
mParent->EndComputePass(*mPass);
164+
mParent->EndComputePass(*mPass, mUsedCanvasContexts);
164165
Cleanup();
165166
}
166167

dom/webgpu/ComputePassEncoder.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class ComputePassEncoder final : public ObjectBase,
5050
nsTArray<RefPtr<const Buffer>> mUsedBuffers;
5151
nsTArray<RefPtr<const ComputePipeline>> mUsedPipelines;
5252

53+
// The canvas contexts of any canvas textures used in bind groups of this
54+
// compute pass.
55+
CanvasContextArray mUsedCanvasContexts;
56+
5357
// programmable pass encoder
5458
private:
5559
void SetBindGroup(uint32_t aSlot, BindGroup* const aBindGroup,
@@ -79,6 +83,11 @@ class ComputePassEncoder final : public ObjectBase,
7983
void InsertDebugMarker(const nsAString& aString);
8084

8185
void End();
86+
87+
// helpers not defined by WebGPU
88+
mozilla::Span<const WeakPtr<CanvasContext>> GetCanvasContexts() const {
89+
return mUsedCanvasContexts;
90+
}
8291
};
8392

8493
} // namespace webgpu

dom/webgpu/Device.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ already_AddRefed<PipelineLayout> Device::CreatePipelineLayout(
477477
already_AddRefed<BindGroup> Device::CreateBindGroup(
478478
const dom::GPUBindGroupDescriptor& aDesc) {
479479
nsTArray<ffi::WGPUBindGroupEntry> entries(aDesc.mEntries.Length());
480+
CanvasContextArray canvasContexts;
480481
for (const auto& entry : aDesc.mEntries) {
481482
ffi::WGPUBindGroupEntry e = {};
482483
e.binding = entry.mBinding;
@@ -490,7 +491,12 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
490491
e.offset = bufBinding.mOffset;
491492
e.size = bufBinding.mSize.WasPassed() ? bufBinding.mSize.Value() : 0;
492493
} else if (entry.mResource.IsGPUTextureView()) {
493-
e.texture_view = entry.mResource.GetAsGPUTextureView()->mId;
494+
auto texture_view = entry.mResource.GetAsGPUTextureView();
495+
e.texture_view = texture_view->mId;
496+
auto context = texture_view->GetTargetContext();
497+
if (context) {
498+
canvasContexts.AppendElement(context);
499+
}
494500
} else if (entry.mResource.IsGPUSampler()) {
495501
e.sampler = entry.mResource.GetAsGPUSampler()->mId;
496502
} else {
@@ -518,7 +524,7 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
518524
mBridge->SendDeviceAction(mId, std::move(bb));
519525
}
520526

521-
RefPtr<BindGroup> object = new BindGroup(this, id);
527+
RefPtr<BindGroup> object = new BindGroup(this, id, std::move(canvasContexts));
522528
object->SetLabel(aDesc.mLabel);
523529

524530
return object.forget();

dom/webgpu/RenderBundle.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ namespace mozilla::webgpu {
1414
GPU_IMPL_CYCLE_COLLECTION(RenderBundle, mParent)
1515
GPU_IMPL_JS_WRAP(RenderBundle)
1616

17-
RenderBundle::RenderBundle(Device* const aParent, RawId aId)
18-
: ChildOf(aParent), mId(aId) {
17+
RenderBundle::RenderBundle(Device* const aParent, RawId aId,
18+
CanvasContextArray&& aCanvasContexts)
19+
: ChildOf(aParent),
20+
mId(aId),
21+
mUsedCanvasContexts(std::move(aCanvasContexts)) {
1922
// TODO: we may be running into this if we finish an encoder twice.
2023
MOZ_RELEASE_ASSERT(aId);
2124
}

dom/webgpu/RenderBundle.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define GPU_RenderBundle_H_
88

99
#include "nsWrapperCache.h"
10+
#include "CanvasContext.h"
1011
#include "ObjectModel.h"
1112

1213
namespace mozilla::webgpu {
@@ -18,13 +19,21 @@ class RenderBundle final : public ObjectBase, public ChildOf<Device> {
1819
GPU_DECL_CYCLE_COLLECTION(RenderBundle)
1920
GPU_DECL_JS_WRAP(RenderBundle)
2021

21-
RenderBundle(Device* const aParent, RawId aId);
22+
RenderBundle(Device* const aParent, RawId aId,
23+
CanvasContextArray&& aCanvasContexts);
2224

2325
const RawId mId;
2426

27+
mozilla::Span<const WeakPtr<CanvasContext>> GetCanvasContexts() const {
28+
return mUsedCanvasContexts;
29+
}
30+
2531
private:
2632
virtual ~RenderBundle();
2733
void Cleanup();
34+
35+
// The canvas contexts of any canvas textures used in this render bundle.
36+
CanvasContextArray mUsedCanvasContexts;
2837
};
2938

3039
} // namespace mozilla::webgpu

0 commit comments

Comments
 (0)