createTextureFromPixels method
Creates a texture already holding pixels.
One call rather than create-then-write, because that is what the engine means every time: a procedural texture and a decoded PNG are both "make me a texture out of these bytes", and a two-step version would leave a window in which a texture exists holding nothing. Whether the backend needs a staging copy, a particular storage mode or a flipped origin to get the bytes there is its own business.
Throws a DeviceResourceException when pixels is not the size the
device wants for a texture of that description (it answered null before
1.0). A loader that would rather lose one texture than the model catches
it where it uploads, which is where a decoder that disagreed about the
dimensions can still be named.
mipLevels are the smaller copies, from half size downwards, and the
texture is built with a chain exactly as long as the list. They are
supplied rather than generated, and that is the same lesson as
linearRepeat: WebGL2 has glGenerateMipmap and Impeller does not, so
letting each backend make its own chain is two backends agreeing by
accident and a third answering differently — at a scale nobody would
attribute to the filter. MipChain.build makes them once, above the seam,
and every backend uploads the same bytes.
Ask features.has(DeviceFeature.manualMipmaps) first. A device that
answers false is not merely slower with a chain; on OpenGL ES 2 without
GL_APPLE_texture_max_level a hand-built chain samples as black.
Implementation
@override
TextureHandle createTextureFromPixels({
required int width,
required int height,
required TextureFormat format,
required ByteData pixels,
List<ByteData>? mipLevels,
}) =>
_guard(
'a ${width}x$height ${format.name} image',
() => webgpuCreateTextureFromPixels(
_gpuDevice,
_textures,
width: width,
height: height,
format: format,
pixels: pixels,
mipLevels: mipLevels,
),
) ??
(throw refuseResource(
'createTextureFromPixels',
'the pixels (or a mip level) are not the size a ${width}x$height '
'${format.name} texture needs, or this device has no spelling '
'for the format',
));