FakeBackend class final

A device that records rather than draws.

Its capabilities are a DeviceFeatures set like every backend's, built from the constructor's flags. The 0.9 surface is off unless a test names it in extraFeatures; a feature named there is recorded — each call becomes a RecordedCall in the pass or in calls — and a feature not named is refused with UnsupportedCapabilityException, exactly as a real backend without it refuses. Compute is recorded, not run, since 1.0.0-rc.1: FakeBackend(compute: true) reports DeviceFeature.compute, makes compute pipelines and opens a FakeComputePass that records every bind and dispatch (computePasses), so a ComputeStep can be tested for what it encodes; extraFeatures still may not name compute.

Inheritance
Mixed-in types

Constructors

FakeBackend({Set<String> missingShaders = const <String>{}, bool supportsWireframe = true, bool supportsAlphaToCoverage = true, bool supportsStencil = true, bool supportsRenderToMip = true, Set<TextureFormat> unsupportedFormats = const <TextureFormat>{}, int maxAnisotropy = 16, int maxColorAttachments = 2, Map<String, StageBindings>? stageBindings, FramebufferOrigin framebufferOrigin = FramebufferOrigin.topLeft, Iterable<DeviceFeature> extraFeatures = const <DeviceFeature>[], Set<String> refusingPipelines = const <String>{}, int? refusedBuilds, bool compute = false})
maxAnisotropy and maxColorAttachments become limits; the flags and extraFeatures become features. See the class doc for what a feature named in extraFeatures does on a fake.

Properties

answerReadback ↔ ByteData Function(TextureHandle texture, ScreenRect region)?
What a readback answers, or null for a region of zeros.
getter/setter pair
backendId → BackendId
The backend's id: the one name a material compiler, a plugin manifest and RuntimeShaders know this backend by, compared exactly.
no setterinherited
backendName → String
The name a refusal from this device gives as its backend. The runtime type by default; a backend overrides it with the name a person knows it by ("WebGPU", "Impeller").
no setterinherited
bindingViolations → List<String>
Declared slots left unbound at a draw, across every pass. See stageBindings.
final
calls → List<RecordedCall>
Every device-level 0.9 call, in order, for a test that wants to know a buffer was written or a copy recorded. Pass-level calls go into the pass's own commands.
final
completesImmediately ↔ bool
Whether onFrameComplete runs its callback at once.
getter/setter pair
computePasses → List<FakeComputePass>
Every compute pass opened, in order, for a test that asks what a step bound and dispatched. Since 1.0.0-rc.1.
final
createdCubeRenderTargets → List<FakeCubeTarget>
Every cube a pass may draw into, with the level count it was asked for, so a test can see that a probe allocated what it meant to.
final
createdTextures → List<RenderTargetDescriptor>
The description of every render target the device made, in order. A target the pool reused is not made again, so this shows pooling working.
final
defaultColorFormat → TextureFormat
The colour format this device prefers.
no setteroverride
defaultDepthStencilFormat → TextureFormat
The depth/stencil format this device prefers. Legitimately TextureFormat.unknown on a context that has none.
no setteroverride
depthRange → DepthRange
What this backend's clip space maps depth onto.
no setteroverride
errors → Stream<DeviceError>
What the device refused after the call that asked, and survived — since 1.0.0-rc.1.
no setteroverride
features → DeviceFeatures
What this device can do — every optional capability, as one set.
no setteroverride
framebufferOrigin → FramebufferOrigin
The engine's own convention by default, so a fake never exercises the remap. The backends that need the other one are covered by running them; a test that pins what the engine hands such a backend asks for FramebufferOrigin.bottomLeft.
final
frames ↔ int
How many times beginFrame was called, a count.
getter/setter pair
gpuTimings → Stream<GpuFrameTimings>
Each frame's GPU timings, a frame or two after it was encoded — since 1.0.0-rc.2, when it replaced onGpuTimings(listener), whose one slot a second caller took from the renderer. A broadcast stream: the renderer, a profiler and a test each listen without taking the others' timings, and a backend measures only while something listens.
no setterinherited
hashCode → int
The hash code for this object.
no setterinherited
hdrColorFormat → TextureFormat
The format to render high dynamic range colour into.
no setteroverride
hdrOutputFormats → List<TextureFormat>
The formats this device can present an extended-range frame in, empty when it can only present standard range.
no setteroverride
isDisposed → bool
Whether dispose has been called, for a test that wants to assert a device was actually torn down rather than merely dropped.
no setter
isLost → bool
Whether the device is lost now, and not restored — the state lost reports the changes of, so a caller that subscribed late can ask. Every backend that reports on lost answers here too.
no setteroverride
isSoftware → bool
Whether this device does its work on the CPU, as the software rasteriser does, rather than on a GPU — since 1.0.0-rc.1.
no setterinherited
limits → DeviceLimits
Sixteen taps and two attachments unless the constructor said otherwise — gfx-50n. Two is a parameter because the device it stands in for cannot be asked: Impeller on OpenGL ES aborts rather than refusing, so there is no way to run the no-MRT path on the hardware that has it. This fake answers what a pass was opened with; CpuDevice, which takes the same number, answers what came out the other end as pixels.
final
linkedPipelines → List<String>
Every pair linked so far, by name and in order, so a test can tell whether a frame linked anything — a renderer that relinked drops every pipeline it held and links each one again, and one it forgot to drop shows up here as a link that did not happen.
final
liveHandleCount → int
How many handles liveHandles holds.
no setter
liveHandles → List<Object>
Every handle this device made and nobody has given back yet, oldest first: textures, geometry buffers, buffers, pipelines and query sets.
no setter
loadedLibraries → List<FakeLoadedShaderLibrary>
Every library loadShaders has handed out, in order, so a test can reach the one an application holds and count its refreshes.
final
lost → Stream<DeviceLoss>
Each time the device stops working: a WebGPU device lost, a WebGL context lost or restored. An external source, so a Stream.
no setteroverride
onBeginRenderPass ↔ void Function(RenderPassDescriptor descriptor)?
Called with each render pass as it is asked for, before it is opened: what it throws is what beginRenderPass throws.
getter/setter pair
overwrites → List<FakeGeometryOverwrite>
Every call overwriteGeometry has recorded, in order — a test asks this rather than the bytes themselves, because this backend keeps none: it records wiring, not content, the same promise uploads already makes.
final
overwrittenTextures → List<FakeTextureOverwrite>
Every call overwriteTexture has recorded, in order — wiring, not content, the same promise uploadedPixels already makes for a whole upload.
final
passes → List<FakePass>
Every pass ever opened, in the order it was opened.
final
pendingFrames → List<void Function()>
Frames whose work the GPU has not "finished".
final
pipelineBuilds → Map<String, int>
How many times each pipeline in refusingPipelines was built at a draw, refused or not: what a test holds the rebuild bound to.
final
pipelineRefusals → PipelineRefusals
The pipelines this device could not build or link, and what to do with a draw that needs one.
no setterinherited
preferredSampleCount → int
Samples to use for multisampled targets, or 1 for none.
no setteroverride
readbacks → List<FakeReadback>
Every readback asked for, in order: which texture and which region.
final
refusedBuilds → int?
How many builds of a pipeline in refusingPipelines fail before one links; null for every build. One is the driver that refused once and links at the rebuild.
final
refusingPipelines → Set<String>
Pipelines, by name, that this fake's driver will not link — the lazily linking OpenGL ES driver a phone falls back to, which accepts a pipeline at createPipeline and refuses it at the first draw.
final
releasedGeometry → List<GeometryBuffer>
Every geometry buffer released, in order.
final
releasedTextures → List<TextureHandle>
What was handed back one at a time, in the order it was handed back.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
shaders → FakeShaderLibrary
The compiled bundle this device was built with.
final
shareableKinds → Set<NativeHandleKind>
The NativeHandleKinds this device can both export and import. Empty on a device without DeviceFeature.sharedTextures, sharedBuffers or sharedFences, which is every backend in this repository today.
no setterinherited
stageBindings → Map<String, StageBindings>?
What each stage declares, by name, or null to accept every bind.
final
supportsOffscreenMsaa ← bool
True, and settable so a test can be the device that answers no — gfx-20n.
no getter
unsupportedFormats → Set<TextureFormat>
The formats this fake says it cannot sample, so a test can be the device that has no BC7 and see what a loader does about it.
final
uploadedMipLevels → List<List<ByteData>?>
The chain each of those came with — null for an upload that brought none — so a test can tell a base level from a base level and its mips.
final
uploadedPixels → List<ByteData>
The bytes of each of those, for a test that cares what colour it was.
final
uploadedTextures → List<RenderTargetDescriptor>
Pixel uploads, in order, so a test can assert what reached the device.
final
uploads → List<GeometryUsage>
Recorded with its usage, because a backend exists that cannot change its mind about one later.
final

Methods

beginComputePass({String? label, PassTimestampWrites? timestampWrites}) → ComputeEncoder
Opens a compute pass; label names it to a debugger and to gpuTimings. timestampWrites (since 1.0) names where the pass writes its start and end GPU times — DeviceFeature.timestampQuery.
override
beginFrame() → void
Tells the backend a new frame is starting.
override
beginRenderPass(RenderPassDescriptor descriptor) → CommandEncoder
Opens a pass and returns the encoder that records into it.
override
beginTransferPass({String? label}) → TransferEncoder
Opens a pass of copies between buffers and textures. Never refused — each copy is gated by its own feature. See TransferEncoder. By default a pass whose every copy refuses by its feature, and whose submit has nothing to send.
override
createBuffer(BufferDescriptor descriptor, {ByteData? contents}) → StorageBuffer
A buffer of BufferDescriptor.lengthInBytes bytes, for the usages it names, holding contents (zeros by default).
override
createComputePipeline(ShaderHandle shader) → ComputePipelineHandle
A pipeline from a compute stage of this device's shader library.
override
createComputePipelineAsync(ShaderHandle shader) → Future<ComputePipelineHandle>
createComputePipeline, asynchronously; see createPipelineAsync. For a caller warming a compute pass up behind a loading screen.
inherited
createComputePipelineFrom(ComputePipelineDescriptor descriptor) → ComputePipelineHandle
The compute pipeline descriptor describes, for createPipelineFrom's reason. By default it builds through createComputePipeline (so a device without DeviceFeature.compute refuses it as compute) and gives it ComputePipelineDescriptor.label.
inherited
createComputePipelineFromAsync(ComputePipelineDescriptor descriptor) → Future<ComputePipelineHandle>
createComputePipelineFrom, asynchronously, through createComputePipelineAsync by default.
inherited
createCubeRenderTarget({required int size, required TextureFormat format, int mipLevels = 1}) → TextureHandle
Allocates a cube texture a pass can draw into, face by face and level by level, with nothing in it yet.
override
createCubeTextureFromPixels({required int size, required TextureFormat format, required List<ByteData> faces, List<List<ByteData>>? mipLevels}) → TextureHandle
Uploads six square images as one cube texture.
override
createFence() → GpuFence
A timeline fence at value zero, which signalFence raises and waitFence waits for — DeviceFeature.sharedFences.
inherited
createPipeline(ShaderHandle vertex, ShaderHandle fragment, {VertexLayoutDescriptor? layout}) → PipelineHandle
Links two stages into something that can be bound.
override
createPipelineAsync(ShaderHandle vertex, ShaderHandle fragment, {VertexLayoutDescriptor? layout}) → Future<PipelineHandle>
createPipeline without holding up the caller: the future completes when the pipeline is linked.
inherited
createPipelineFrom(PipelineDescriptor descriptor) → PipelineHandle
The pipeline descriptor describes: the entry point every pipeline input after 1.0 arrives through.
inherited
createPipelineFromAsync(PipelineDescriptor descriptor) → Future<PipelineHandle>
createPipelineFrom without holding up the caller, as createPipelineAsync is to createPipeline. By default it goes through createPipelineAsync, so a backend that compiles off the thread there does so here too.
inherited
createQuerySet(QueryType type, int count) → QuerySet
A set of count queries of type — DeviceFeature.occlusionQuery, DeviceFeature.timestampQuery or DeviceFeature.pipelineStatisticsQuery, the feature QueryType.feature names.
override
createRenderBundleEncoder(RenderBundleDescriptor descriptor) → RenderBundleEncoder
Opens an encoder whose draws are kept as a RenderBundle, to be replayed into any pass whose attachments match descriptor — DeviceFeature.renderBundles. See RenderBundleEncoder for what a bundle cannot record. An override calls RenderBundleDescriptor.checkFeatures once it has the feature.
override
createTexture(TextureDescriptor descriptor) → TextureHandle
A brand-new texture matching descriptor, with the single TextureHandle that will ever stand for it, contents undefined until written.
override
createTextureFromPixels({required int width, required int height, required TextureFormat format, required ByteData pixels, List<ByteData>? mipLevels}) → TextureHandle
Creates a texture already holding pixels.
override
dispose() → void
Says DeviceLossReason.destroyed on lost the first time, as every backend owes for its own dispose, and closes lost and errors.
override
exportBuffer(StorageBuffer buffer, {NativeHandleKind? kind}) → NativeHandle
exportTexture for a buffer — DeviceFeature.sharedBuffers.
inherited
exportFence(GpuFence fence, {NativeHandleKind? kind}) → NativeHandle
fence as a NativeHandle of kind, for another device to import.
inherited
exportTexture(TextureHandle texture, {NativeHandleKind? kind}) → NativeHandle
texture's memory as a NativeHandle of kind (the first of shareableKinds by default), for another device or API to import — DeviceFeature.sharedTextures. The handle is valid while texture is.
inherited
finishOldestFrame() → void
Lets the oldest unfinished frame complete.
importBuffer(NativeHandle handle, BufferDescriptor descriptor) → StorageBuffer
importTexture for a buffer — DeviceFeature.sharedBuffers.
inherited
importFence(NativeHandle handle) → GpuFence
A fence over the one handle names, which another device made.
inherited
importTexture(NativeHandle handle, TextureDescriptor descriptor) → TextureHandle
A texture shaped like descriptor over the memory handle names, which another device or API made and keeps — DeviceFeature.sharedTextures. Released like any texture; the memory stays its maker's.
inherited
labelOf(Object resource) → String?
The label setLabel gave resource, or null when it has none.
inherited
loadShaders(ByteData bytes) → Future<LoadedShaderLibrary>
Decodes the bundle — so bytes that are not one are refused the way every real backend refuses them — and answers its names. No section is read: a fake compiles nothing, which is also the software rasteriser's answer.
override
lose(DeviceLoss loss) → void
Loses the device as a backend would, for a test of whoever listens to lost: isLost becomes true unless loss is the restored event that ends a recoverable loss, and loss goes out on lost.
mapBuffer(StorageBuffer buffer, MapMode mode, {int offsetInBytes = 0, int? sizeInBytes}) → Future<MappedBuffer>
Maps sizeInBytes bytes (to the end by default) of buffer from offsetInBytes into host memory, once every pass submitted before this call is done with it — DeviceFeature.mappedBuffers.
override
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onFrameComplete(void whenDone()) → void
Runs whenDone once the GPU has finished with the frame being encoded now.
override
overwriteGeometry(GeometryBuffer target, int offsetInBytes, ByteData bytes) → void
Writes bytes into target starting offsetInBytes into it, in place.
override
overwriteTexture(TextureHandle target, ByteData rgba, {ScreenRect? region, int mipLevel = 0}) → Future<void>
Overwrites region (the whole texture by default) of target's base level with rgba — raw RGBA8 bytes, region.width * region.height * 4 of them, row-major from the top the same way readback answers them.
override
readback(TextureHandle texture, {ScreenRect? region}) → Future<ByteData>
Refuses what the contract refuses, records the rest, and answers zeros unless answerReadback says otherwise. A whole texture outside readbackFormats is "converted" to zeros of its size, and recorded as a readback of all of it.
override
readBuffer(StorageBuffer buffer) → Future<ByteData>
Zeros of the buffer's length: a fake keeps no bytes. Refused for a buffer that was not made host-readable, as every backend refuses it.
override
readBufferSync(StorageBuffer buffer, {int offsetInBytes = 0, int? sizeInBytes}) → ByteData
The bytes of buffer (a range of them), read back in the calling turn.
override
readQueryResults(QuerySet querySet, {int first = 0, int? count}) → Future<List<int>>
Zeros: nothing was drawn, so nothing passed and no time went by.
override
refuse(DeviceFeature feature, {String? reason}) → UnsupportedCapabilityException
The refusal for feature on this device, for a default body or a backend's own gate to throw: throw refuse(DeviceFeature.compute).
inherited
refuseResource(String operation, String reason, {Object? cause}) → DeviceResourceException
The refusal for a request this device has the feature for and still cannot honour, for a backend to throw from operation: throw refuseResource('createTextureFromPixels', 'the pixels are …').
inherited
releaseComputePipeline(ComputePipelineHandle pipeline) → void
Releases a pipeline createComputePipeline made, as releasePipeline.
override
releaseFence(GpuFence fence) → void
Releases a fence createFence or importFence made.
inherited
releaseGeometry(GeometryBuffer geometry) → void
Releases one geometry buffer, rather than waiting for the whole device to go.
override
releasePipeline(PipelineHandle pipeline) → void
Releases a pipeline createPipeline made. Does nothing by default: a backend whose pipelines are reclaimed with their last reference is right to.
override
releaseQuerySet(QuerySet querySet) → void
Releases one query set, as releaseStorageBuffer releases a buffer.
override
releaseRenderBundle(RenderBundle bundle) → void
Releases a bundle createRenderBundleEncoder recorded.
inherited
releaseSampler(SamplerDescriptor sampler) → void
Gives back what this device made to sample with sampler, if it made anything.
inherited
releaseStorageBuffer(StorageBuffer buffer) → void
Releases one storage buffer, as releaseGeometry releases geometry.
override
releaseTexture(TextureHandle texture) → void
Gives one back, rather than waiting for the whole device to go.
override
reportError(DeviceError error) → void
Reports error on errors, as a backend whose API answers late would — for a test of whoever listens.
setLabel(Object resource, String label) → void
Names resource — a TextureHandle, GeometryBuffer, StorageBuffer, PipelineHandle, QuerySet or RenderBundle this device made — for a GPU debugger, a frame capture and the memory report.
inherited
signalFence(GpuFence fence, int value) → void
Raises fence to value on this device's queue once the work submitted before this call is done. value only grows.
inherited
textureFormatSupport(TextureFormat format) → TextureFormatSupport
What format can be used for here: sampled, filtered, rendered, blended, multisampled, resolved, used as depth, bound as storage.
override
toString() → String
A string representation of this object.
inherited
uploadGeometry(ByteData bytes, GeometryUsage usage) → GeometryBuffer
Uploads geometry that will outlive the frame.
override
waitFence(GpuFence fence, int value) → void
Holds the work this device submits after this call until fence reaches value. The CPU does not wait.
inherited
writeBuffer(StorageBuffer target, int offsetInBytes, ByteData bytes) → void
Writes bytes into target at offsetInBytes, in place. Visible starting the next pass, as overwriteGeometry; an offset and length that do not fit throw an ArgumentError before anything is written.
override
writeTexture(TextureHandle target, ByteData data, {TextureRegion? region, int mipLevel = 0, int? bytesPerRow}) → void
Writes data into region (the whole level by default) of level mipLevel of target, in target's own format, rows bytesPerRow apart (tightly packed by default; a compressed format counts rows of blocks). Visible starting the next pass, as overwriteGeometry.
override

Operators

operator ==(Object other) → bool
The equality operator.
inherited