()
| 504 | } |
| 505 | |
| 506 | function renderPendingRgbaFrame() { |
| 507 | if (!pendingRgbaFrame || !mainThreadWebGPU || !directCanvas) return; |
| 508 | |
| 509 | const { buffer, receivedAt } = pendingRgbaFrame; |
| 510 | pendingRgbaFrame = null; |
| 511 | |
| 512 | if (buffer.byteLength < 24) return; |
| 513 | |
| 514 | const metadataOffset = buffer.byteLength - 24; |
| 515 | const meta = new DataView(buffer, metadataOffset, 24); |
| 516 | const strideBytes = meta.getUint32(0, true); |
| 517 | const height = meta.getUint32(4, true); |
| 518 | const width = meta.getUint32(8, true); |
| 519 | |
| 520 | if (width > 0 && height > 0) { |
| 521 | const frameDataSize = strideBytes * height; |
| 522 | if (strideBytes === 0 || buffer.byteLength - 24 < frameDataSize) return; |
| 523 | |
| 524 | const frameData = new Uint8ClampedArray(buffer, 0, frameDataSize); |
| 525 | const renderStart = performance.now(); |
| 526 | |
| 527 | if (directCanvas.width !== width || directCanvas.height !== height) { |
| 528 | directCanvas.width = width; |
| 529 | directCanvas.height = height; |
| 530 | } |
| 531 | |
| 532 | const timing = renderFrameWebGPU( |
| 533 | mainThreadWebGPU, |
| 534 | frameData, |
| 535 | width, |
| 536 | height, |
| 537 | strideBytes, |
| 538 | ); |
| 539 | |
| 540 | storeRenderedFrame(frameData, width, height, strideBytes, false); |
| 541 | recordRender( |
| 542 | performance.now() - renderStart, |
| 543 | "webgpu", |
| 544 | timing, |
| 545 | receivedAt, |
| 546 | ); |
| 547 | onmessage({ width, height }); |
| 548 | } |
| 549 | } |
| 550 | |
| 551 | function schedulePendingRgbaFrame(buffer: ArrayBuffer, receivedAt: number) { |
| 552 | pendingRgbaFrame = { buffer, receivedAt }; |
no test coverage detected