createTextureFromPixels method
- required int width,
- required int height,
- required TextureFormat format,
- required ByteData pixels,
- List<
ByteData> ? mipLevels,
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.
Null when pixels is not the size the device wants for a texture of that
description — which is how a decoder that disagreed about the dimensions
degrades to "no texture" rather than taking the whole model down.
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 supportsMipmaps 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,
}) {
final spec = RenderTargetSpec(
width: width,
height: height,
format: format,
storageMode: StorageMode.hostVisible,
);
uploadedTextures.add(spec);
uploadedPixels.add(pixels);
return createTexture(spec);
}