Unverified Commit 0a9588f3 authored by Jeremy Soller's avatar Jeremy Soller Committed by GitHub

Merge pull request #44 from robbycerantola/fast_image

Fast image rendering with falling back to legacy function
parents 13ce578f 183f9576
......@@ -13,6 +13,9 @@ keywords = [
"ui",
]
[dependencies]
time = "*"
[features]
default = []
no_std = []
......
extern crate orbclient;
extern crate time;
use orbclient::{Color, Window, Renderer, EventOption};
const TIMES:i32 = 100;
fn main() {
//let (width, height) = orbclient::get_display_size().unwrap();
let mut window = Window::new(10,
10,
800,
600,
"IMAGE BENCHMARK")
.unwrap();
window.set(Color::rgb(255,255,255));
//create image data : a green square
let data = vec![Color::rgba(100,200,10,20);412500];
let data2 = vec![Color::rgba(200,100,10,20);412500];
let data3 = vec![Color::rgba(10,100,200,20);800];
//draw image benchmarking
println!("Benchmarking implementations to draw an image on window:");
let mut t = time::now();
for _i in 0..TIMES {
window.image_legacy(10,10,750,550, &data[..]);
}
let mut t2 = time::now();
let dt = (t2-t)/TIMES;
println!("image_legacy {:?}",dt );
t = time::now();
for _i in 0..TIMES {
window.image_fast(140,240,750,550, &data2[..]);
}
t2 = time::now();
let dt2 = (t2-t)/TIMES;
println!("image_fast {:?}",dt2);
println!("-------------------------");
println!("difference {:?}", dt-dt2);
t = time::now();
for _i in 0..TIMES {
window.image(0,0,800,1, &data3[..]);
}
t2 = time::now();
let dt3 = (t2-t)/TIMES;
println!("image wrapper {:?}",dt3);
window.sync();
'events: loop {
for event in window.events() {
match event.to_option() {
EventOption::Quit(_quit_event) => break 'events,
EventOption::Mouse(evt) => println!("At position {:?} pixel color is : {:?}",(evt.x,evt.y), window.getpixel(evt.x,evt.y )),
event_option => println!("{:?}", event_option)
}
}
}
}
......@@ -60,6 +60,8 @@ fn main() {
window.char(200, 200, '═', Color::rgb(0, 0, 0));
window.char(208, 200, '═', Color::rgb(0, 0, 0));
// testing for non existent x,y position : does not panic but returns Color(0,0,0,0)
let _non_existent_pixel = window.getpixel(width as i32 +10,height as i32 +10);
......
......@@ -68,3 +68,16 @@ impl fmt::Debug for Color {
write!(f, "{:#010X}", {self.data})
}
}
#[cfg(test)]
mod tests {
#[test]
fn partial_eq() {
use Color;
assert_eq!(true, Color::rgb(1,2,3) == Color::rgba(1,2,3,200));
assert_eq!(false, Color::rgb(1,2,3) == Color::rgba(11,2,3,200));
assert_eq!(true, Color::rgba(1,2,3,200) == Color::rgba(1,2,3,200));
}
}
......@@ -294,8 +294,17 @@ pub trait Renderer {
}
/// Display an image
// TODO: Improve speed
fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
//check if image is inside window
if (w + start_x as u32) > self.width() {
self.image_legacy(start_x, start_y, w, h, data);
}else{
self.image_fast(start_x, start_y, w, h, data);
}
}
// TODO: Improve speed
fn image_legacy(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
let mut i = 0;
for y in start_y..start_y + h as i32 {
for x in start_x..start_x + w as i32 {
......@@ -307,6 +316,45 @@ pub trait Renderer {
}
}
// Speed improved, but image has to be all inside of window boundary
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_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;
*old = ((o_a << 24) | (o_r << 16) | (o_g << 8) | o_b) + ((alpha << 24) | (n_r << 16) | (n_g << 8) | n_b);
}
}
}
}
}
/// Draw a linear gradient in a rectangular region
#[cfg(not(feature="no_std"))]
......
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