perf(wgpu_atlas): upload identity-format textures from the caller's slice
BGRA atlas uploads (every viewer video frame on macOS) were staged through swizzle_upload_data's to_vec() into pending_uploads — a full-frame CPU copy per upload. Non-swizzled formats now write_texture directly from the borrowed bytes; only the RGBA swizzle and the not-yet-allocated fallback keep the owned staging path.
This commit is contained in:
@@ -246,14 +246,49 @@ impl WgpuAtlasState {
|
||||
}
|
||||
|
||||
fn upload_texture(&mut self, id: AtlasTextureId, bounds: Bounds<DevicePixels>, bytes: &[u8]) {
|
||||
let data = self
|
||||
.storage
|
||||
.get(id)
|
||||
.map(|texture| swizzle_upload_data(bytes, texture.format))
|
||||
.unwrap_or_else(|| bytes.to_vec());
|
||||
|
||||
self.pending_uploads
|
||||
.push(PendingUpload { id, bounds, data });
|
||||
// Identity-format uploads (BGRA on macOS, i.e. every viewer video
|
||||
// frame) write straight from the caller's slice: queueing an owned
|
||||
// `to_vec()` first was a full-frame CPU copy per upload. Only the
|
||||
// RGBA swizzle and the not-yet-allocated fallback still stage an
|
||||
// owned buffer. `write_texture` enqueues on the same queue the
|
||||
// frame is drawn with, so the ordering guarantees are identical to
|
||||
// the batched `pending_uploads` flush.
|
||||
let Some(texture) = self.storage.get(id) else {
|
||||
let data = bytes.to_vec();
|
||||
self.pending_uploads
|
||||
.push(PendingUpload { id, bounds, data });
|
||||
return;
|
||||
};
|
||||
if texture.format == wgpu::TextureFormat::Rgba8Unorm {
|
||||
let data = swizzle_upload_data(bytes, texture.format);
|
||||
self.pending_uploads
|
||||
.push(PendingUpload { id, bounds, data });
|
||||
return;
|
||||
}
|
||||
let bytes_per_pixel = texture.bytes_per_pixel();
|
||||
self.queue.write_texture(
|
||||
wgpu::TexelCopyTextureInfo {
|
||||
texture: &texture.texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d {
|
||||
x: bounds.origin.x.0 as u32,
|
||||
y: bounds.origin.y.0 as u32,
|
||||
z: 0,
|
||||
},
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
},
|
||||
bytes,
|
||||
wgpu::TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(bounds.size.width.0 as u32 * bytes_per_pixel as u32),
|
||||
rows_per_image: None,
|
||||
},
|
||||
wgpu::Extent3d {
|
||||
width: bounds.size.width.0 as u32,
|
||||
height: bounds.size.height.0 as u32,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn flush_uploads(&mut self) {
|
||||
|
||||
Reference in New Issue
Block a user