Skip to content

Commit f1ebe83

Browse files
committed
Bug 1972921 - Track canvas textures used in bind groups r=webgpu-reviewers,nical
Differential Revision: https://phabricator.services.mozilla.com/D255033
1 parent 39b16da commit f1ebe83

24 files changed

+627
-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
@@ -99,7 +99,8 @@ void CommandEncoder::Cleanup() {
9999

100100
RefPtr<WebGPUChild> CommandEncoder::GetBridge() { return mBridge; }
101101

102-
void CommandEncoder::TrackPresentationContext(CanvasContext* aTargetContext) {
102+
void CommandEncoder::TrackPresentationContext(
103+
WeakPtr<CanvasContext> aTargetContext) {
103104
if (aTargetContext) {
104105
mPresentationContexts.AppendElement(aTargetContext);
105106
}
@@ -256,7 +257,8 @@ void CommandEncoder::ResolveQuerySet(QuerySet& aQuerySet, uint32_t aFirstQuery,
256257
aQueryCount, aDestination.mId, aDestinationOffset);
257258
}
258259

259-
void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass) {
260+
void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass,
261+
CanvasContextArray& aCanvasContexts) {
260262
// Because this can be called during child Cleanup, we need to check
261263
// that the bridge is still alive.
262264
if (!mBridge) {
@@ -271,11 +273,16 @@ void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass) {
271273
}
272274
mState = CommandEncoderState::Open;
273275

276+
for (const auto& context : aCanvasContexts) {
277+
TrackPresentationContext(context);
278+
}
279+
274280
ffi::wgpu_compute_pass_finish(mBridge->GetClient(), mParent->mId, mId,
275281
&aPass);
276282
}
277283

278-
void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass) {
284+
void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass,
285+
CanvasContextArray& aCanvasContexts) {
279286
// Because this can be called during child Cleanup, we need to check
280287
// that the bridge is still alive.
281288
if (!mBridge) {
@@ -290,6 +297,10 @@ void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass) {
290297
}
291298
mState = CommandEncoderState::Open;
292299

300+
for (const auto& context : aCanvasContexts) {
301+
TrackPresentationContext(context);
302+
}
303+
293304
ffi::wgpu_render_pass_finish(mBridge->GetClient(), mParent->mId, mId, &aPass);
294305
}
295306

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(
@@ -159,7 +160,7 @@ void ComputePassEncoder::End() {
159160
return;
160161
}
161162
MOZ_ASSERT(!!mPass);
162-
mParent->EndComputePass(*mPass);
163+
mParent->EndComputePass(*mPass, mUsedCanvasContexts);
163164
Cleanup();
164165
}
165166

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
@@ -441,6 +441,7 @@ already_AddRefed<PipelineLayout> Device::CreatePipelineLayout(
441441
already_AddRefed<BindGroup> Device::CreateBindGroup(
442442
const dom::GPUBindGroupDescriptor& aDesc) {
443443
nsTArray<ffi::WGPUBindGroupEntry> entries(aDesc.mEntries.Length());
444+
CanvasContextArray canvasContexts;
444445
for (const auto& entry : aDesc.mEntries) {
445446
ffi::WGPUBindGroupEntry e = {};
446447
e.binding = entry.mBinding;
@@ -454,7 +455,12 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
454455
e.offset = bufBinding.mOffset;
455456
e.size = bufBinding.mSize.WasPassed() ? bufBinding.mSize.Value() : 0;
456457
} else if (entry.mResource.IsGPUTextureView()) {
457-
e.texture_view = entry.mResource.GetAsGPUTextureView()->mId;
458+
auto texture_view = entry.mResource.GetAsGPUTextureView();
459+
e.texture_view = texture_view->mId;
460+
auto context = texture_view->GetTargetContext();
461+
if (context) {
462+
canvasContexts.AppendElement(context);
463+
}
458464
} else if (entry.mResource.IsGPUSampler()) {
459465
e.sampler = entry.mResource.GetAsGPUSampler()->mId;
460466
} else {
@@ -478,7 +484,7 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
478484
RawId id =
479485
ffi::wgpu_client_create_bind_group(mBridge->GetClient(), mId, &desc);
480486

481-
RefPtr<BindGroup> object = new BindGroup(this, id);
487+
RefPtr<BindGroup> object = new BindGroup(this, id, std::move(canvasContexts));
482488
object->SetLabel(aDesc.mLabel);
483489

484490
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)