Skip to content

Commit 256a231

Browse files
committed
Optimize the filling code for bitmap
1 parent 3a17f8b commit 256a231

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

benches/benches/parallel.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ fn draw_func_2x1_parallel_and_blit(c: &mut Criterion) {
8484
c.bench_function("parallel::draw_func_2x1_parallel_and_blit", |b| {
8585
b.iter(|| {
8686
let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area();
87-
let areas = root.split_evenly((2,1));
87+
let areas = root.split_evenly((2, 1));
8888
let mut elements: Vec<_> = areas
8989
.iter()
9090
.map(|area| area.dim_in_pixel())
@@ -116,9 +116,12 @@ fn draw_func_2x1_inplace_parallel(c: &mut Criterion) {
116116
)
117117
};
118118

119-
[upper, lower]
120-
.par_iter_mut()
121-
.for_each(|b| draw_plot(&BitMapBackend::with_buffer(*b, (W, H / 2)).into_drawing_area(), 2.0));
119+
[upper, lower].par_iter_mut().for_each(|b| {
120+
draw_plot(
121+
&BitMapBackend::with_buffer(*b, (W, H / 2)).into_drawing_area(),
122+
2.0,
123+
)
124+
});
122125
})
123126
});
124127
}
@@ -128,7 +131,7 @@ fn draw_func_2x1_seq(c: &mut Criterion) {
128131
c.bench_function("parallel::draw_func_2x1_seq", |b| {
129132
b.iter(|| {
130133
let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area();
131-
root.split_evenly((2,1))
134+
root.split_evenly((2, 1))
132135
.iter_mut()
133136
.for_each(|area| draw_plot(area, 2.0));
134137
})
@@ -138,9 +141,9 @@ fn draw_func_2x1_seq(c: &mut Criterion) {
138141
criterion_group! {
139142
name = parallel_group;
140143
config = Criterion::default().sample_size(10);
141-
targets =
142-
draw_func_1x1_seq,
143-
draw_func_4x4_seq,
144+
targets =
145+
draw_func_1x1_seq,
146+
draw_func_4x4_seq,
144147
draw_func_4x4_parallel_and_blit,
145148
draw_func_2x1_parallel_and_blit,
146149
draw_func_2x1_inplace_parallel,

src/drawing/backend_impl/bitmap.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,35 @@ impl<'a> BitMapBackend<'a> {
242242
.for_each(|e| *e = r);
243243
}
244244
} else {
245-
for y in y0..=y1 {
246-
let start = (y * w as i32 + x0) as usize;
247-
let count = (x1 - x0 + 1) as usize;
248-
let mut iter = dst[(start * 3)..((start + count) * 3)].iter_mut();
249-
for _ in 0..(x1 - x0 + 1) {
250-
*iter.next().unwrap() = r;
251-
*iter.next().unwrap() = g;
252-
*iter.next().unwrap() = b;
245+
let count = (x1 - x0 + 1) as usize;
246+
if count < 8 {
247+
for y in y0..=y1 {
248+
let start = (y * w as i32 + x0) as usize;
249+
let mut iter = dst[(start * 3)..((start + count) * 3)].iter_mut();
250+
for _ in 0..(x1 - x0 + 1) {
251+
*iter.next().unwrap() = r;
252+
*iter.next().unwrap() = g;
253+
*iter.next().unwrap() = b;
254+
}
255+
}
256+
} else {
257+
for y in y0..=y1 {
258+
let start = (y * w as i32 + x0) as usize;
259+
let start_ptr = &mut dst[start * 3] as *mut u8 as *mut (u8, u8, u8, u8, u8, u8);
260+
let slice =
261+
unsafe { std::slice::from_raw_parts_mut(start_ptr, (count - 1) / 2) };
262+
for p in slice.iter_mut() {
263+
unsafe {
264+
let ptr = p as *mut (u8, u8, u8, u8, u8, u8) as *mut u64;
265+
*ptr = std::mem::transmute([r, g, b, r, g, b, 0, 0]);
266+
}
267+
}
268+
269+
for idx in (slice.len() * 2)..count {
270+
dst[start * 3 + idx * 3] = r;
271+
dst[start * 3 + idx * 3 + 1] = g;
272+
dst[start * 3 + idx * 3 + 2] = b;
273+
}
253274
}
254275
}
255276
}
@@ -318,7 +339,21 @@ impl<'a> DrawingBackend for BitMapBackend<'a> {
318339

319340
if from.0 == to.0 || from.1 == to.1 {
320341
if alpha >= 1.0 {
321-
self.fill_rect_fast(from, to, r, g, b);
342+
if from.1 == to.1 {
343+
self.fill_rect_fast(from, to, r, g, b);
344+
} else {
345+
let w = self.get_size().0 as i32;
346+
let dst = self.get_raw_pixel_buffer();
347+
let (mut y0, mut y1) = (from.1, to.1);
348+
if y0 > y1 {
349+
std::mem::swap(&mut y0, &mut y1);
350+
}
351+
for y in y0..=y1 {
352+
dst[(y * w + from.0) as usize * 3] = r;
353+
dst[(y * w + from.0) as usize * 3 + 1] = g;
354+
dst[(y * w + from.0) as usize * 3 + 2] = b;
355+
}
356+
}
322357
} else {
323358
self.blend_rect_fast(from, to, r, g, b, alpha);
324359
}

0 commit comments

Comments
 (0)