import type { ClipRect } from '../types/context.js'; import type { GpuTimer } from './gpuTimer.js'; import type { VertexBufferManager } from './vertexManager.js'; export type DrawCounts = [vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number]; export interface QueueElement { pipeline: GPURenderPipeline; drawCounts: DrawCounts; vertexBuffers: GPUBuffer[]; bindGroups: GPUBindGroup[]; clip?: ClipRect; /** * Drawn somewhere other than the frame. A run of these breaks the frame's * pass, fills a cleared target, and the composite that follows reads it back. * `mask` is coverage alone (shaders/maskComposite.ts) and `layer` is the * mark's own colour over a copy of the frame (shaders/blendComposite.ts). */ pass?: 'mask' | 'layer'; /** Where a mask run draws, for a clip path that needs a target of its own. */ maskView?: GPUTextureView; /** Where that run resolves to, where it is multisampled. */ maskResolve?: GPUTextureView; } /** Where a frame draws, beyond its own attachment. */ export interface FrameTargets { /** What the frame resolves into, which a backdrop copy reads. */ target: GPUTexture; maskView: GPUTextureView; /** Multisampled when the frame is, in which case `layerResolve` follows it. */ layerView: GPUTextureView; layerResolve: GPUTextureView | null; backdrop: GPUTexture; } export interface RenderBatchInfo { device: GPUDevice; vertexManager: VertexBufferManager; pipeline: GPURenderPipeline; clip?: ClipRect; bindGroups: GPUBindGroup[]; /** Vertices per instance. Defaults to a quad. */ vertexCount?: number; } /** Builds the draw that folds a layer back into the frame. */ export type Compositor = (blend: string, clip: ClipRect | undefined) => QueueElement; /** * Collects draw calls for one frame and submits them in a single command * buffer. Each WebGPURenderer instance owns its own queue, so multiple * views on a page do not interfere with each other. */ export declare class RenderQueue { private queue; private batch; private batchInfo; private offFrame; private compositor; /** Starts a frame, with the compositor its layered draws fold back through. */ startFrame(compositor: Compositor): void; /** Whether anything this frame draws somewhere other than the frame itself. */ drawsOffFrame(): boolean; enqueue(element: QueueElement): void; /** * Starts collecting instances that share one pipeline (e.g. the segments * of many line marks) so they can be issued as a single draw call. * A subsequent draw with a different pipeline flushes the batch, keeping * the paint order of the scenegraph intact. */ setupBatch(info: RenderBatchInfo): void; /** Adds one mark's instances to the open batch. */ queueBatchInstance(values: ArrayLike): void; private flushBatch; /** * Encodes all queued draws into render passes and submits them. * Scissor rects are clamped to the attachment size. WebGPU validation * rejects scissor rects that extend beyond the render target. */ submit(device: GPUDevice, renderPassDescriptor: GPURenderPassDescriptor, attachmentSize: [width: number, height: number], timer?: GpuTimer | null, targets?: FrameTargets | null): void; }