Commit 22baf994 authored by robbycerantola's avatar robbycerantola

faster pixel() and image_fast()

parent 4bf16d05
......@@ -41,7 +41,7 @@ fn main() {
}
t2 = time::now();
let dt = (t2-t)/TIMES;
println!("image_legacy {:?}",dt );
println!("image_legacy (pixel_fast) {:?}",dt );
t = time::now();
......
......@@ -14,6 +14,7 @@ fn main() {
.unwrap();
let (win_w, win_h) = (width/2, height/2);
// top left -> bottom rigth
window.linear_gradient(0, 0, win_w/3, win_h, 0, 0, (win_w/3) as i32, (win_h/2) as i32, Color::rgb(128,128,128), Color::rgb(255,255,255));
// horizontal gradient
......@@ -79,7 +80,7 @@ fn main() {
window.mode().set(Mode::Overwrite); // set window drawing mode to Overwrite from now on
window.rect(300, 220, 80, 80, Color::rgb(100,100,100));
//Possibly draw a hole in the window replacing alpha channel ?? (Only in Orbital, not in SDL2)
//Draw a hole in the window replacing alpha channel (Only in Orbital, not in SDL2)
window.rect(300, 100, 80, 80, Color::rgba(10,10,10,1));
//Draw a transparent rectangle over window content
......
......@@ -37,8 +37,8 @@ pub enum WindowFlag {
#[derive(Clone, Copy, Debug)]
pub enum Mode {
Blend, //Composite
Overwrite //Replace
Blend, //Composite
Overwrite //Replace
}
#[cfg(all(not(feature="no_std"), target_os = "redox"))]
......
......@@ -54,10 +54,14 @@ pub trait Renderer {
///Draw a pixel
fn pixel(&mut self, x: i32, y: i32, color: Color) {
let replace = match self.mode().get() {
Mode::Blend => false,
Mode::Overwrite => true,
match self.mode().get() {
Mode::Blend => self.pixel_fast(x, y, color),
Mode::Overwrite => self.pixel_legacy(x, y, color, true),
};
}
#[inline(always)]
fn pixel_legacy(&mut self, x: i32, y: i32, color: Color, replace: bool) {
let w = self.width();
let h = self.height();
let data = self.data_mut();
......@@ -86,6 +90,31 @@ pub trait Renderer {
//}
}
}
//faster pixel implementation (multiplexing)
#[inline(always)]
fn pixel_fast(&mut self, x: i32, y: i32, color: Color) {
let w = self.width();
let h = self.height();
let data = self.data_mut();
if x >= 0 && y >= 0 && x < w as i32 && y < h as i32 {
let new = color.data;
let alpha = (new >> 24) & 0xFF;
let old = unsafe{ &mut data[y as usize * w as usize + x as usize].data};
let n_alpha = 255 - alpha;
let rb = ((n_alpha * ( *old & 0x00FF00FF)) +
(alpha * (new & 0x00FF00FF))) >> 8;
let ag = (n_alpha * ((*old & 0xFF00FF00)) >> 8) +
( alpha * (0x01000000 | ((new & 0xFF00FF00) >>8)));
*old = (rb & 0x00FF00FF) | (ag & 0xFF00FF00);
}
}
/// Draw a piece of an arc. Negative radius will fill in the inside
fn arc(&mut self, x0: i32, y0: i32, radius: i32, parts: u8, color: Color) {
......@@ -378,6 +407,7 @@ pub trait Renderer {
}
// Speed improved, but image has to be all inside of window boundary
/*
#[inline(always)]
fn image_fast (&mut self, start_x: i32, start_y: i32, w: u32, h: u32, image_data: &[Color]) {
let window_w = self.width() as usize;
......@@ -417,6 +447,43 @@ pub trait Renderer {
}
}
*/
#[inline(always)]
fn image_fast(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, image_data: &[Color]) {
let window_w = self.width() as usize;
let window_len = self.data().len();
let data = self.data_mut();
let w = w as usize;
let start_x = start_x as usize;
let start_y = start_y as usize;
for i in 0..(w * h as usize) {
let y0 = i / w;
let y = y0 + start_y;
let x = start_x + i - (y0 * w);
let window_index = y * window_w + x;
if window_index < window_len && i < image_data.len(){
let new = image_data[i].data;
let alpha = (new >> 24) & 0xFF;
if alpha > 0 {
let old = unsafe{ &mut data[window_index].data};
if alpha >= 255 {
*old = new;
} else {
let n_alpha = 255 - alpha;
let rb = ((n_alpha * ( *old & 0x00FF00FF)) +
(alpha * (new & 0x00FF00FF))) >> 8;
let ag = (n_alpha * ((*old & 0xFF00FF00)) >> 8) +
( alpha * (0x01000000 | ((new & 0xFF00FF00) >>8)));
*old = (rb & 0x00FF00FF) | (ag & 0xFF00FF00);
}
}
}
}
}
///Render an image using parallel threads if possible
//Works in Linux but not in Redox !
......@@ -463,17 +530,13 @@ pub trait Renderer {
if alpha >= 255 {
*old = new;
} else {
let n_r = (((new >> 16) & 0xFF) * alpha) >> 8;
let n_g = (((new >> 8) & 0xFF) * alpha) >> 8;
let n_b = ((new & 0xFF) * alpha) >> 8;
let n_alpha = 255 - alpha;
let o_a = (((*old >> 24) & 0xFF) * n_alpha) >> 8;
let o_r = (((*old >> 16) & 0xFF) * n_alpha) >> 8;
let o_g = (((*old >> 8) & 0xFF) * n_alpha) >> 8;
let o_b = ((*old & 0xFF) * n_alpha) >> 8;
let rb = ((n_alpha * ( *old & 0x00FF00FF)) +
(alpha * (new & 0x00FF00FF))) >> 8;
let ag = (n_alpha * ((*old & 0xFF00FF00)) >> 8) +
( alpha * (0x01000000 | ((new & 0xFF00FF00) >>8)));
*old = ((o_a << 24) | (o_r << 16) | (o_g << 8) | o_b) + ((alpha << 24) | (n_r << 16) | (n_g << 8) | n_b);
*old = (rb & 0x00FF00FF) | (ag & 0xFF00FF00);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment