diff options
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts')
-rw-r--r-- | dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts index 609dacb907..633d88d2b8 100644 --- a/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts +++ b/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts @@ -40,6 +40,27 @@ class GPUContextTest extends GPUTest { return ctx; } + + expectTextureDestroyed(texture: GPUTexture, expectDestroyed = true) { + this.expectValidationError(() => { + // Try using the texture in a render pass. Because it's a canvas texture + // it should have RENDER_ATTACHMENT usage. + assert((texture.usage & GPUTextureUsage.RENDER_ATTACHMENT) !== 0); + const encoder = this.device.createCommandEncoder(); + const pass = encoder.beginRenderPass({ + colorAttachments: [ + { + view: texture.createView(), + loadOp: 'clear', + storeOp: 'store', + }, + ], + }); + pass.end(); + // Submitting should generate a validation error if the texture is destroyed. + this.queue.submit([encoder.finish()]); + }, expectDestroyed); + } } export const g = makeTestGroup(GPUContextTest); @@ -170,7 +191,7 @@ g.test('multiple_frames') // Ensure that each frame a new texture object is returned. t.expect(currentTexture !== prevTexture); - // Ensure that texture contents are transparent black. + // Ensure that the texture's initial contents are transparent black. t.expectSingleColor(currentTexture, currentTexture.format, { size: [currentTexture.width, currentTexture.height, 1], exp: { R: 0, G: 0, B: 0, A: 0 }, @@ -178,7 +199,8 @@ g.test('multiple_frames') } if (clearTexture) { - // Clear the texture to test that texture contents don't carry over from frame to frame. + // Fill the texture with a non-zero color, to test that texture + // contents don't carry over from frame to frame. const encoder = t.device.createCommandEncoder(); const pass = encoder.beginRenderPass({ colorAttachments: [ @@ -215,10 +237,8 @@ g.test('multiple_frames') } } - // Call frameCheck for the first time from requestAnimationFrame - // To make sure two frameChecks are run in different frames for onscreen canvas. - // offscreen canvas doesn't care. - requestAnimationFrame(frameCheck); + // Render the first frame immediately. The rest will be triggered recursively. + frameCheck(); }); }); @@ -235,6 +255,8 @@ g.test('resize') // Trigger a resize by changing the width. ctx.canvas.width = 4; + t.expectTextureDestroyed(prevTexture); + // When the canvas resizes the texture returned by getCurrentTexture should immediately begin // returning a new texture matching the update dimensions. let currentTexture = ctx.getCurrentTexture(); @@ -263,7 +285,6 @@ g.test('resize') t.expect(currentTexture.height === ctx.canvas.height); t.expect(prevTexture.width === 4); t.expect(prevTexture.height === 2); - prevTexture = currentTexture; // Ensure that texture contents are transparent black. t.expectSingleColor(currentTexture, currentTexture.format, { @@ -271,13 +292,31 @@ g.test('resize') exp: { R: 0, G: 0, B: 0, A: 0 }, }); - // Simply setting the canvas width and height values to their current values should not trigger - // a change in the texture. - ctx.canvas.width = 4; - ctx.canvas.height = 4; - - currentTexture = ctx.getCurrentTexture(); - t.expect(prevTexture === currentTexture); + // HTMLCanvasElement behaves differently than OffscreenCanvas + if (t.params.canvasType === 'onscreen') { + // Ensure canvas goes back to defaults when set to negative numbers. + ctx.canvas.width = -1; + currentTexture = ctx.getCurrentTexture(); + t.expect(currentTexture.width === 300); + t.expect(currentTexture.height === 4); + + ctx.canvas.height = -1; + currentTexture = ctx.getCurrentTexture(); + t.expect(currentTexture.width === 300); + t.expect(currentTexture.height === 150); + + // Setting the canvas width and height values to their current values should + // still trigger a change in the texture. + prevTexture = ctx.getCurrentTexture(); + const { width, height } = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + + t.expectTextureDestroyed(prevTexture); + + currentTexture = ctx.getCurrentTexture(); + t.expect(prevTexture !== currentTexture); + } }); g.test('expiry') @@ -307,6 +346,14 @@ TODO: test more canvas types, and ways to update the rendering .combine('prevFrameCallsite', ['runInNewCanvasFrame', 'requestAnimationFrame'] as const) .combine('getCurrentTextureAgain', [true, false] as const) ) + .beforeAllSubcases(t => { + if ( + t.params.prevFrameCallsite === 'requestAnimationFrame' && + typeof requestAnimationFrame === 'undefined' + ) { + throw new SkipTestCase('requestAnimationFrame not available'); + } + }) .fn(t => { const { canvasType, prevFrameCallsite, getCurrentTextureAgain } = t.params; const ctx = t.initCanvasContext(t.params.canvasType); |