Skip to content

Commit 661418b

Browse files
authored
Merge pull request #8704 from processing/fix/feedback
Fix/feedback
2 parents d9b9a9a + b8737a7 commit 661418b

4 files changed

Lines changed: 60 additions & 5 deletions

File tree

src/webgpu/p5.RendererWebGPU.js

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,21 @@ function rendererWebGPU(p5, fn) {
454454
const _b = args[2] || 0;
455455
const _a = args[3] || 0;
456456

457-
// If PENDING and no custom framebuffer, clear means stay UNPROMOTED
458-
if (this._frameState === FRAME_STATE.PENDING && !this.activeFramebuffer()) {
459-
this._frameState = FRAME_STATE.UNPROMOTED;
457+
// If PENDING and no custom framebuffer, clear means stay UNPROMOTED.
458+
// However, if we are still in setup (frameCount == 0), we must promote
459+
// so that mainFramebuffer gets the cleared content. This ensures that if
460+
// draw() later promotes without a copy, it starts from the correct state
461+
// rather than a stale mainFramebuffer.
462+
// Note: a mid-draw-loop transition from UNPROMOTED back to PROMOTED
463+
// (i.e. calling background() some frames but not others) will still
464+
// lose intermediate UNPROMOTED frame content.
465+
if (this._frameState !== FRAME_STATE.PROMOTED && !this.activeFramebuffer()) {
466+
if (this._pInst.frameCount > 0) {
467+
this._frameState = FRAME_STATE.UNPROMOTED;
468+
} else {
469+
this._promoteToFramebufferWithoutCopy();
470+
// clear() then targets mainFramebuffer via activeFramebuffer()
471+
}
460472
}
461473

462474
this._finishActiveRenderPass();
@@ -1143,8 +1155,11 @@ function rendererWebGPU(p5, fn) {
11431155

11441156
_resetBuffersBeforeDraw() {
11451157
this._finishActiveRenderPass();
1158+
11461159
// Set state to PENDING - we'll decide on first draw
1147-
this._frameState = FRAME_STATE.PENDING;
1160+
if (this._pInst.frameCount > 0) {
1161+
this._frameState = FRAME_STATE.PENDING;
1162+
}
11481163

11491164
// Clear depth buffer but DON'T start any render pass yet
11501165
const activeFramebuffer = this.activeFramebuffer();
@@ -1255,6 +1270,8 @@ function rendererWebGPU(p5, fn) {
12551270
// once we're drawing to the framebuffer, because normally
12561271
// those are reset.
12571272
const savedModelMatrix = this.states.uModelMatrix.copy();
1273+
this.states.uModelMatrix.set(this.states.uModelMatrix.copy());
1274+
this.states.uModelMatrix.reset();
12581275
this.mainFramebuffer.defaultCamera.set(this.states.curCamera);
12591276

12601277
this.mainFramebuffer.begin();
@@ -1263,6 +1280,11 @@ function rendererWebGPU(p5, fn) {
12631280
}
12641281

12651282
_promoteToFramebufferWithoutCopy() {
1283+
// Already promoted this frame
1284+
if (this._frameState === FRAME_STATE.PROMOTED) {
1285+
return;
1286+
}
1287+
12661288
// Ensure mainFramebuffer matches canvas size
12671289
if (this.mainFramebuffer.width !== this.width ||
12681290
this.mainFramebuffer.height !== this.height) {
@@ -1277,6 +1299,8 @@ function rendererWebGPU(p5, fn) {
12771299

12781300
// Preserve transformation state
12791301
const savedModelMatrix = this.states.uModelMatrix.copy();
1302+
this.states.uModelMatrix.set(this.states.uModelMatrix.copy());
1303+
this.states.uModelMatrix.reset();
12801304
this.mainFramebuffer.defaultCamera.set(this.states.curCamera);
12811305

12821306
// Begin rendering to mainFramebuffer
@@ -1590,7 +1614,6 @@ function rendererWebGPU(p5, fn) {
15901614
}
15911615
this.flushDraw();
15921616

1593-
// this._pInst.background('red');
15941617
this._pInst.push();
15951618
this.states.setValue('enableLighting', false);
15961619
this.states.setValue('activeImageLight', null);

test/unit/visual/cases/webgpu.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,4 +1423,33 @@ visualSuite("WebGPU", function () {
14231423
}
14241424
);
14251425
});
1426+
1427+
visualSuite('Feedback', function() {
1428+
visualTest(
1429+
'Drawing accumulates across frames when background is set in setup',
1430+
async function(p5, screenshot) {
1431+
await p5.createCanvas(50, 50, p5.WEBGPU);
1432+
1433+
// Set an initial background before the draw loop starts.
1434+
// This should persist into the first draw frame.
1435+
p5.background('red');
1436+
1437+
return new Promise(resolve => {
1438+
let frame = 0;
1439+
p5.draw = function() {
1440+
// Draw circles without clearing, so they accumulate
1441+
p5.noStroke();
1442+
p5.fill('blue');
1443+
p5.circle(-15 + frame * 15, 0, 10);
1444+
frame++;
1445+
if (frame >= 3) {
1446+
p5.noLoop();
1447+
screenshot().then(resolve);
1448+
}
1449+
};
1450+
p5.loop();
1451+
});
1452+
}
1453+
);
1454+
});
14261455
});
390 Bytes
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"numScreenshots": 1
3+
}

0 commit comments

Comments
 (0)