Skip to content

ExternalTexture

An external texture is one shared producer identity. Platform-specific classes derive from ExternalTexture; pass their std::shared_ptr directly to Image. There is no separate source-to-handle conversion.

Platform Producer choices
Windows windows::PixelTexture for copied CPU rows; windows::D3D11Texture for immutable shared GPU snapshots.
Android android::BitmapTexture, android::GlTexture, or android::SurfaceStreamTexture.
iOS / macOS PixelBufferTexture for Core Video frames; MetalTexture for GPU snapshots in the platform namespace.
Linux linux::PixelTexture, linux::GlTexture, or linux::GdkTexture.
Web web::VideoFrameTexture for a browser VideoFrame.

Include the matching platform header explicitly. These producer types are not interchangeable across renderer backends.

This integration fragment receives an existing RGBA byte span:

auto texture = std::make_shared<windows::PixelTexture>(Size{320.0F, 180.0F});
texture->Publish({
.pixel_width = 640,
.pixel_height = 360,
.bytes_per_row = 640 * 4,
.format = windows::PixelFormat::Rgba8888,
.pixels = pixels,
});
View preview = Image(texture).Fit(ImageFit::Contain);

PixelTexture::Publish copies required rows before returning, so this producer may reuse the source bytes. The input is straight-alpha untagged sRGB; the renderer receives its owned representation. Do not generalize this CPU-copy rule to all platform objects.

Windows D3D11 and Apple Metal publication create stable snapshots; serialize producer access as required by the concrete header. D3D11 needs a supported single-sampled BGRA source and matching graphics adapter, and is unavailable in Windows 7 compatibility builds.

Android/Linux GlTexture::PublishCurrent runs with the producer context current and publishes a stable copied snapshot. Linux GdkTexture instead retains an already immutable GDK texture: the application must not mutate its backing content afterward. Web publication follows the browser event-loop and VideoFrame lifetime contract.

Keep device/context loss, fences, and platform handles out of shared UI code. A module can expose a typed producer while owning the platform-specific work.

Intrinsic size is set once in logical DIPs. The published pixel dimensions may change without changing that layout intent. Replace the texture identity if logical size really changes.

Publication schedules repaint without recomposition or paint-sequence rerecording. IsActive() helps avoid unnecessary production, but it is not an unmount callback. Stop work explicitly in your service/lifecycle cleanup, then call Finish(); the last published frame remains available to consumers.

Test first publication, empty producer, changing frame resolution, hidden consumers, replacement, unmount, shutdown, context/device loss, and publication from the documented thread. A shared-header compile is not GPU or device validation.

Use PlatformView instead when the embedded object must own platform-control interaction. See the platform-specific reference for includes.