Skip to content

Commit 61e21b5

Browse files
committed
Garbage-initialize buffers with cfg(debug_assertions)
To help make it clear that the buffer isn't zero-initialize / catch mistakes where the user was relying on it. For example, drawing like this is incorrect: ``` // Fill with blue. for (_, _, pixel) in buffer.pixels_iter() { pixel.b = 0xff; pixel.a = 0xff; } ```
1 parent 22ba885 commit 61e21b5

File tree

6 files changed

+20
-6
lines changed

6 files changed

+20
-6
lines changed

src/backends/android.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
114114
}
115115

116116
let buffer =
117-
vec![Pixel::default(); native_window_buffer.stride() * native_window_buffer.height()];
117+
vec![Pixel::INIT; native_window_buffer.stride() * native_window_buffer.height()];
118118

119119
Ok(BufferImpl {
120120
native_window_buffer,

src/backends/cg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
279279
fn next_buffer(&mut self, alpha_mode: AlphaMode) -> Result<BufferImpl<'_>, SoftBufferError> {
280280
let buffer_size = util::byte_stride(self.width as u32) as usize * self.height / 4;
281281
Ok(BufferImpl {
282-
buffer: util::PixelBuffer(vec![Pixel::default(); buffer_size]),
282+
buffer: util::PixelBuffer(vec![Pixel::INIT; buffer_size]),
283283
width: self.width,
284284
height: self.height,
285285
color_space: &self.color_space,

src/backends/orbital.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Orbital
132132
)
133133
} else {
134134
Pixels::Buffer(util::PixelBuffer(vec![
135-
Pixel::default();
135+
Pixel::INIT;
136136
self.width as usize
137137
* self.height as usize
138138
]))

src/backends/web.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for WebImpl
182182
if self.size != Some((width, height)) {
183183
self.buffer_presented = false;
184184
self.buffer
185-
.resize(total_len(width.get(), height.get()), Pixel::default());
185+
.resize(total_len(width.get(), height.get()), Pixel::INIT);
186186
self.canvas.set_width(width.get());
187187
self.canvas.set_height(height.get());
188188
self.size = Some((width, height));

src/backends/x11.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
397397
.swbuf_err("Failed to fetch image from window")?;
398398

399399
if reply.depth == self.depth && reply.visual == self.visual_id {
400-
let mut out = vec![Pixel::default(); reply.data.len() / size_of::<Pixel>()];
400+
let mut out = vec![Pixel::INIT; reply.data.len() / size_of::<Pixel>()];
401401
// SAFETY: `Pixel` can be re-interpreted as `[u8; 4]`.
402402
let out_u8s = unsafe {
403403
slice::from_raw_parts_mut(
@@ -557,7 +557,7 @@ impl Buffer {
557557
match self {
558558
Buffer::Shm(ref mut shm) => shm.alloc_segment(conn, num_bytes),
559559
Buffer::Wire(wire) => {
560-
wire.resize(num_bytes / size_of::<Pixel>(), Pixel::default());
560+
wire.resize(num_bytes / size_of::<Pixel>(), Pixel::INIT);
561561
Ok(())
562562
}
563563
}

src/pixel.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ impl Pixel {
151151
pub const fn new_bgra(b: u8, g: u8, r: u8, a: u8) -> Self {
152152
Self { r, g, b, a }
153153
}
154+
155+
/// A reasonable value to initialize buffers with.
156+
///
157+
/// Users should redraw the entire buffer when `buffer.age() == 0`, they shouldn't rely on this.
158+
#[allow(unused)] // Only used on some backends.
159+
pub(crate) const INIT: Self = if cfg!(debug_assertions) {
160+
// Half-transparent mostly-red, this will panic in `Buffer::present` (unless the user
161+
// chose a different alpha mode), which is desirable since we don't want this pixel to ever
162+
// show up.
163+
Self::new_rgba(0xff, 0x11, 0x22, 0x7f)
164+
} else {
165+
// Zero-initialization is often a lot faster.
166+
Self::new_rgba(0x00, 0x00, 0x00, 0x00)
167+
};
154168
}
155169

156170
// TODO: Implement `Add`/`Mul`/similar `std::ops` like `rgb` does?

0 commit comments

Comments
 (0)