readbackFormats top-level constant
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,
};