createTextureFromPixels method

  1. @override
TextureHandle createTextureFromPixels({
  1. required int width,
  2. required int height,
  3. required TextureFormat format,
  4. required ByteData pixels,
  5. 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.

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',
    ));