readback abstract method

Future<ByteData> readback(
  1. TextureHandle texture, {
  2. ScreenRect? region,
})
inherited

The pixels of region — the whole texture by default — as they stand at this point in the queue: premultiplied RGBA8, row-major from the top-left, the region's own width times four per row.

One layout, named, because the only thing anybody does with these is compare them against pixels that came from somewhere else — and two sides of a comparison that disagree about premultiplication differ on every translucent texel while looking identical on screen.

The one way to read a texture back, since 1.0. readPixels was a second call for the same bytes that answered null where this throws; a finished picture (a golden run, a probe, a test) and last frame's answer while this frame goes on (an exposure meter, the id under the cursor) are both this. Two promises make the second work:

  • The copy is queued where it was asked for. A pass submitted after this call, drawing into the same texture, does not reach the bytes: they are the texture as the passes before this call left it. The conformance check a readback returns the frame before clears red, asks, clears blue, and gets red.
  • Nothing here stalls the caller for an eight-bit texture. The hardware backends copy on the GPU and resolve the future when the queue reports the copy done — flutter_gpu through submit's completion callback, WebGL2 through a pixel-pack buffer and a fence — so the frame being encoded is not held up by a frame the GPU is still on. The software rasteriser has nothing to wait for and answers at once, which is the truth there.

The future therefore usually completes a frame or two later.

region is stated from the top left, in the texture's own pixels, like every rectangle in this interface, and must lie inside the texture. One pixel is a legitimate region and the cheapest one: the editor's pick reads exactly that.

A whole texture in another format is converted, which is how a float target (the engine's HDR colour) is looked at: each backend draws or converts it into eight-bit RGBA on its own path, which may wait for the GPU. See readbackConverts. A region of one is refused, because a partial conversion is the place three backends would disagree.

Throws an ArgumentError for what cannot be read at all — a deviceTransient texture, a multisampled one, a cube, a region outside the texture, a region of a texture outside readbackFormats — because the handle carries every one of those facts and the caller can ask before requesting. Throws a DeviceResourceException when the device has the texture and still cannot hand its pixels over: a format this backend has no conversion for.

Implementation

Future<ByteData> readback(TextureHandle texture, {ScreenRect? region});