Unverified Commit 6287bb72 authored by Jeremy Soller's avatar Jeremy Soller Committed by GitHub

Merge pull request #48 from robbycerantola/master

Faster pixel() and even faster image_fast()
parents 4bf16d05 d6727c1f
......@@ -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) {
......@@ -379,7 +408,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]) {
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();
......@@ -400,17 +429,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);
}
}
}
......@@ -463,17 +488,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