gardesk/garbg / 1578a8c

Browse files

reuse BGRA conversion buffer in animation renderer instead of allocating per frame

Authored by espadonne
SHA
1578a8ce714bde6d08f012d3e6da5b2442237345
Parents
434d22e
Tree
7250f83

1 changed file

StatusFile+-
M garbg/src/x11/animation.rs 17 12
garbg/src/x11/animation.rsmodified
@@ -76,21 +76,24 @@ impl DoubleBuffer {
7676
 pub struct AnimationRenderer {
7777
     /// Double buffer for smooth rendering
7878
     buffer: DoubleBuffer,
79
+    /// Reusable BGRA conversion buffer (avoids per-frame allocation)
80
+    bgra_buf: Vec<u8>,
7981
 }
8082
 
8183
 impl AnimationRenderer {
8284
     /// Create a new animation renderer
8385
     pub fn new(conn: &Connection) -> Result<Self> {
8486
         let buffer = DoubleBuffer::new(conn)?;
85
-        Ok(Self { buffer })
87
+        Ok(Self { buffer, bgra_buf: Vec::new() })
8688
     }
8789
 
8890
     /// Render a frame to the back buffer
8991
     pub fn render_frame(&mut self, conn: &mut Connection, frame: &image::RgbaImage) -> Result<()> {
9092
         let (width, height) = self.buffer.dimensions();
9193
 
92
-        // Convert RGBA to BGRA (X11 native format)
93
-        let bgra_data = rgba_to_bgra(frame);
94
+        // Convert RGBA to BGRA in-place using reusable buffer
95
+        rgba_to_bgra_into(frame, &mut self.bgra_buf);
96
+        let bgra_data = &self.bgra_buf;
9497
 
9598
         let gc = conn.gc();
9699
         let x11_conn = conn.conn();
@@ -188,14 +191,16 @@ impl AnimationRenderer {
188191
     }
189192
 }
190193
 
191
-/// Convert RGBA to BGRA (X11 native format for 32-bit visuals)
192
-fn rgba_to_bgra(image: &image::RgbaImage) -> Vec<u8> {
193
-    let mut bgra = Vec::with_capacity(image.len());
194
-    for pixel in image.pixels() {
195
-        bgra.push(pixel[2]); // B
196
-        bgra.push(pixel[1]); // G
197
-        bgra.push(pixel[0]); // R
198
-        bgra.push(pixel[3]); // A
194
+/// Convert RGBA to BGRA into a reusable buffer (X11 native format for 32-bit visuals)
195
+fn rgba_to_bgra_into(image: &image::RgbaImage, buf: &mut Vec<u8>) {
196
+    let raw = image.as_raw();
197
+    buf.clear();
198
+    buf.reserve(raw.len());
199
+    // Process 4 bytes at a time (one pixel)
200
+    for chunk in raw.chunks_exact(4) {
201
+        buf.push(chunk[2]); // B
202
+        buf.push(chunk[1]); // G
203
+        buf.push(chunk[0]); // R
204
+        buf.push(chunk[3]); // A
199205
     }
200
-    bgra
201206
 }