readbackFormats top-level constant

Set<TextureFormat> const readbackFormats

The formats a readback hands back as they are: four bytes per pixel, one per channel, which is what GraphicsDevice.readback promises.

Any other format is refused rather than converted, and the refusal is what keeps three backends answering alike. Asked for a half-float target — the engine's own HDR colour — WebGL2's readPixels(RGBA, UNSIGNED_BYTE) is an INVALID_OPERATION that leaves the pack buffer at the zeros it was made with, so the future completes successfully with a black picture; flutter_gpu would convert through toByteData and answer with the picture; the software rasteriser would clamp its floats and answer with a third thing. A caller with a float texture reads it back through readPixels, which is allowed to be slow, or draws it into an eight-bit target first, which is what the luminance pass does.

Two layouts and not four, which is the same argument applied a second time. The sRGB twins were in here on the grounds that they are eight bits per channel too, and that is the wrong test: the question is whether three backends hand back the same bytes, and for an sRGB texture nothing said they would. flutter_gpu reads through asImage().toByteData(rawRgba), which is entitled to hand back the linear values the encoding stands for; WebGL2's readPixels hands back the encoded bytes as they sit; the software rasteriser rounds its own linear floats. Nothing in this repository asked — every readback target the engine declares is r8g8b8a8UNormInt — so a format admitted here was a promise no check ever made and no caller ever tested. BGRA stays because it is the default colour format of a backend that has one, and because a swizzle is a layout rather than a conversion: the same four bytes in a different order.

Implementation

const Set<TextureFormat> readbackFormats = <TextureFormat>{
  TextureFormat.r8g8b8a8UNormInt,
  TextureFormat.b8g8r8a8UNormInt,
};