Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dirty flag #23

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions src/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::error::Error;

#[derive(Debug)]
pub struct Canvas {
is_dirty: bool,
pub width: usize,
pub height: usize,
pub pixels: Vec<u32>,
Expand All @@ -13,12 +14,22 @@ pub struct Canvas {
impl Canvas {
pub fn new(width: usize, height: usize, pixels: &[u32]) -> Self {
Canvas {
is_dirty: true,
pixels: pixels.to_owned(),
width,
height,
}
}

pub fn from_dimensions(width: usize, height: usize) -> Self {
Canvas {
is_dirty: true,
width,
height,
pixels: vec![0; width * height],
}
}

pub fn from_color(width: usize, height: usize, r: u8, g: u8, b: u8) -> Self {
let mut pixels: Vec<u32> = vec![];
for _ in 0..width {
Expand All @@ -27,18 +38,40 @@ impl Canvas {
}
}
Canvas {
is_dirty: true,
pixels: pixels.to_owned(),
width,
height,
}
}

#[inline(always)]
pub fn is_dirty(&self) -> bool {
self.is_dirty
}

#[inline(always)]
pub fn set_dirty(&mut self) {
self.is_dirty = true;
}

#[inline(always)]
pub fn reset_dirty_flag(&mut self) {
self.is_dirty = false;
}

pub fn get_pixel(&mut self, x: usize, y: usize) -> u32 {
let curr_index = y * self.width + x;
self.pixels[curr_index]
}

pub fn set_pixel(&mut self, x: usize, y: usize, color: u32) {
self.internal_set_pixel(x, y, color);
self.is_dirty = true;
}

#[inline(always)]
pub fn internal_set_pixel(&mut self, x: usize, y: usize, color: u32) {
let curr_index = y * self.width + x;
self.pixels[curr_index] = color;
}
Expand All @@ -52,13 +85,16 @@ impl Canvas {
let end_y = isize::min(y + canvas.height as isize, self.height as isize);
let start_x = isize::max(x, 0);
let end_x = isize::min(x + canvas.width as isize, self.width as isize);
if (end_x - start_x) * (end_y - start_y) > 0 {
self.is_dirty = true;
}
for ry in start_y..end_y {
let len = ((end_x - start_x) as isize) as usize;
let cur_index = ((ry * self.width as isize + start_x) as isize) as usize;
let r_index = (((ry - y) * canvas.width as isize + (start_x - x)) as isize) as usize;
let (_, right) = self.pixels.split_at_mut(cur_index);
let (_, r_right) = canvas.pixels.split_at(r_index);
right[..len].copy_from_slice(&r_right[..len])
right[..len].copy_from_slice(&r_right[..len]);
}
Ok(())
}
Expand All @@ -78,6 +114,9 @@ impl Canvas {
let end_y = isize::min(y + canvas.height as isize, self.height as isize);
let start_x = isize::max(x, 0);
let end_x = isize::min(x + canvas.width as isize, self.width as isize);
if (end_x - start_x) * (end_y - start_y) > 0 {
self.is_dirty = true;
}
for ry in start_y..end_y {
for rx in start_x..end_x {
let b_index = ((ry - y) * canvas.width as isize + (rx - x)) as usize;
Expand All @@ -98,6 +137,7 @@ impl Canvas {
return Err("cannot copy in canvas that isn't same size".into());
}
self.pixels.copy_from_slice(&canvas.pixels);
self.is_dirty = true;
Ok(())
}

Expand All @@ -111,9 +151,10 @@ impl Canvas {
let dy = -(y1 - y0).abs();
let sy = if y0 < y1 { 1 } else { -1 };
let mut err = dx + dy; /* error value e_xy */
self.is_dirty = true;
loop {
/* loop */
self.set_pixel(x0 as usize, y0 as usize, color);
self.internal_set_pixel(x0 as usize, y0 as usize, color);
if x0 == x1 && y0 == y1 {
break;
}
Expand Down
22 changes: 13 additions & 9 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,7 @@ impl Config {

let w = fb.width();
let h = fb.height();
let mut canvas = Canvas {
width: w,
height: h,
pixels: vec![0; w * h],
};

let mut canvas = Canvas::from_dimensions(w, h);
if let Err(err) = fb.setup() {
// try to shut down because because being stuck in graphics mode is really bad
fb.shutdown()?;
Expand All @@ -100,7 +95,10 @@ impl Config {

match f(&mut canvas, Event::Startup) {
Ok(RunResponse::Draw) => {
fb.write_frame(&canvas.pixels);
if canvas.is_dirty() {
fb.write_frame(&canvas.pixels);
canvas.reset_dirty_flag();
}
}
Ok(RunResponse::Exit) => {
fb.shutdown()?;
Expand Down Expand Up @@ -166,7 +164,10 @@ impl Config {
match timer_rx.try_recv() {
Ok(t) => match f(&mut canvas, t) {
Ok(RunResponse::Draw) => {
fb.write_frame(&canvas.pixels);
if canvas.is_dirty() {
fb.write_frame(&canvas.pixels);
canvas.reset_dirty_flag();
}
}
Ok(RunResponse::Exit) => {
fb.shutdown()?;
Expand All @@ -186,7 +187,10 @@ impl Config {
match swipe_rx.try_recv() {
Ok(s) => match f(&mut canvas, Event::Swipe(s.clone())) {
Ok(RunResponse::Draw) => {
fb.write_frame(&canvas.pixels);
if canvas.is_dirty() {
fb.write_frame(&canvas.pixels);
canvas.reset_dirty_flag();
}
}
Ok(RunResponse::Exit) => {
fb.shutdown()?;
Expand Down