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 never available: a fake runs no
stage, and extraFeatures may not name it.
- Inheritance
-
- Object
- GraphicsDevice
- FakeBackend
- 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}) -
maxAnisotropyandmaxColorAttachmentsbecome limits; the flags andextraFeaturesbecome features. See the class doc for what a feature named inextraFeaturesdoes 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 → String
-
The backend's id: the one name a material compiler, a plugin manifest
and
RuntimeShadersknow 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
-
createdCubeRenderTargets
→ List<
({TextureFormat format, int mipLevels, int size})> -
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> -
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
- 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
-
getter/setter pair
- 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
- 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
-
overwrites
→ List<
({Object backend, int lengthInBytes, int offsetInBytes})> -
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<
({TextureFormat format, int mipLevel, ScreenRect region})> -
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<
({ScreenRect region, TextureHandle texture})> -
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
createPipelineand refuses it at the first draw.final -
releasedGeometry
→ List<
GeometryBuffer> -
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
-
The NativeHandleKinds this device can both export and import. Empty
on a device without
DeviceFeature.sharedTextures,sharedBuffersorsharedFences, 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;
labelnames it to a debugger and to onGpuTimings.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
submithas 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
descriptordescribes, for createPipelineFrom's reason. By default it builds through createComputePipeline (so a device withoutDeviceFeature.computerefuses 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< ? mipLevels}) → TextureHandleByteData> > -
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
descriptordescribes: 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
countqueries oftype—DeviceFeature.occlusionQuery,DeviceFeature.timestampQueryorDeviceFeature.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.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 -
Releases every persistent resource this device holds — the textures and
geometry buffers handed out by createTexture, createTextureFromPixels,
createCubeTextureFromPixels, createCubeRenderTarget and
uploadGeometry.
override
-
exportBuffer(
StorageBuffer buffer, {NativeHandleKind? kind}) → NativeHandle -
exportTexture for a buffer —
DeviceFeature.sharedBuffers.inherited -
exportFence(
GpuFence fence, {NativeHandleKind? kind}) → NativeHandle -
fenceas a NativeHandle ofkind, for another device to import.inherited -
exportTexture(
TextureHandle texture, {NativeHandleKind? kind}) → NativeHandle -
texture's memory as a NativeHandle ofkind(the first of shareableKinds by default), for another device or API to import —DeviceFeature.sharedTextures. The handle is valid whiletextureis.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
handlenames, which another device made.inherited -
importTexture(
NativeHandle handle, TextureDescriptor descriptor) → TextureHandle -
A texture shaped like
descriptorover the memoryhandlenames, 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
lossis therestoredevent that ends a recoverable loss, andlossgoes out on lost. -
mapBuffer(
StorageBuffer buffer, MapMode mode, {int offsetInBytes = 0, int? sizeInBytes}) → Future< MappedBuffer> -
Maps
sizeInBytesbytes (to the end by default) ofbufferfromoffsetInBytesinto 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
whenDoneonce the GPU has finished with the frame being encoded now.override -
onGpuTimings(
void listener(GpuFrameTimings timings)?) → void -
Sets where each frame's GPU timings go, a frame or two after it was
encoded; null stops them. The engine does not call it on a device whose
features lack
DeviceFeature.gpuTimestamps; a backend without the feature may still answer a caller that asks, with what it can measure and its doc saying what that is (Impeller times each labelled pass from submission to completion, and puts it on the Dart timeline).override -
overwriteGeometry(
GeometryBuffer target, int offsetInBytes, ByteData bytes) → void -
Writes
bytesintotargetstartingoffsetInBytesinto it, in place.override -
overwriteTexture(
TextureHandle target, ByteData rgba, {ScreenRect? region, int mipLevel = 0}) → Future< void> -
Overwrites
region(the whole texture by default) oftarget's base level withrgba— raw RGBA8 bytes,region.width * region.height * 4of 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
featureon 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.
inherited
-
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
-
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
fencetovalueon this device's queue once the work submitted before this call is done.valueonly grows.inherited -
textureFormatSupport(
TextureFormat format) → TextureFormatSupport -
What
formatcan 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
fencereachesvalue. The CPU does not wait.inherited -
writeBuffer(
StorageBuffer target, int offsetInBytes, ByteData bytes) → void -
Writes
bytesintotargetatoffsetInBytes, 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
dataintoregion(the whole level by default) of levelmipLeveloftarget, intarget's own format, rowsbytesPerRowapart (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