Fix black screen: convert ARGB8888 to BGRA8 in client display

Server (PixmanRenderer) outputs ARGB8888, client GPU texture expects
BGRA8. Added byte-order conversion in update_frame(). Also changed
texture format from Bgra8UnormSrgb to Bgra8Unorm for correct colors.
This commit is contained in:
Till Wegmueller 2026-04-07 18:06:41 +02:00
parent ab8f9e0d03
commit 6b15ee819e

View file

@ -132,7 +132,7 @@ impl Display {
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
format: wgpu::TextureFormat::Bgra8Unorm,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
@ -246,9 +246,8 @@ impl Display {
/// Upload framebuffer pixel data to the GPU texture.
///
/// `pixel_data` must be BGRA8 format, `width * height * 4` bytes.
/// If the server sends ARGB8888, the caller should convert byte order
/// before calling this method.
/// `pixel_data` is ARGB8888 format from the server (PixmanRenderer).
/// This method converts to BGRA8 for the GPU texture.
pub fn update_frame(&self, pixel_data: &[u8]) {
let expected = (self.width * self.height * 4) as usize;
if pixel_data.len() != expected {
@ -259,9 +258,18 @@ impl Display {
return;
}
// Convert ARGB8888 → BGRA8: [A,R,G,B] → [B,G,R,A]
let mut bgra = Vec::with_capacity(pixel_data.len());
for pixel in pixel_data.chunks_exact(4) {
bgra.push(pixel[3]); // B
bgra.push(pixel[2]); // G
bgra.push(pixel[1]); // R
bgra.push(pixel[0]); // A
}
self.queue.write_texture(
self.frame_texture.as_image_copy(),
pixel_data,
&bgra,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(self.width * 4),