recode GAM interface to send one tile at a time

Don't add Tiles to ObjectList because it greatly inflates
the amount of RAM required to sling tiles around
This commit is contained in:
bunnie 2022-06-15 01:32:12 +08:00
parent 5421a20050
commit d39c319c05
3 changed files with 43 additions and 23 deletions

View file

@ -11,8 +11,6 @@ pub enum GamObjectType {
Circ(Circle),
Rect(Rectangle),
RoundRect(RoundedRectangle),
#[cfg(feature="ditherpunk")]
Tile(Tile),
}
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)]
@ -20,6 +18,12 @@ pub struct GamObject {
pub canvas: Gid,
pub obj: GamObjectType,
}
#[cfg(feature="ditherpunk")]
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)]
pub struct GamTile {
pub canvas: Gid,
pub tile: Tile,
}
#[derive(Debug, Copy, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct GamObjectList {
pub canvas: Gid,
@ -121,6 +125,10 @@ pub(crate) enum Opcode {
// draws an object
RenderObject, //(GamObject),
RenderObjectList,
// draws a tile. this is *not* part of the ObjectList because then every vector object suddenly also carries
// the allocation burden of a bitmap tile.
#[cfg(feature="ditherpunk")]
RenderTile,
// renders a TextView
RenderTextView, //(TextView),

View file

@ -197,13 +197,16 @@ impl Gam {
}
#[cfg(feature="ditherpunk")]
pub fn draw_bitmap(&self, gid: Gid, bm: &Bitmap) -> Result<(), xous::Error> {
let mut list = GamObjectList::new(gid);
for (_i, tile) in bm.iter().enumerate(){
list.push(GamObjectType::Tile(*tile)).unwrap();
let gt = GamTile {
tile: *tile,
canvas: gid,
};
let buf = Buffer::into_buf(gt).or(Err(xous::Error::InternalError))?;
buf.lend(self.conn, Opcode::RenderTile.to_u32().unwrap())
.map(|_| ())?;
};
let buf = Buffer::into_buf(list).or(Err(xous::Error::InternalError))?;
buf.lend(self.conn, Opcode::RenderObjectList.to_u32().unwrap())
.map(|_| ())
Ok(())
}
pub fn draw_circle(&self, gid: Gid, circ: Circle) -> Result<(), xous::Error> {
let go = GamObject {

View file

@ -305,6 +305,31 @@ fn main() -> ! {
let ret = api::Return::ContentCanvasReturn(context_mgr.get_content_canvas(req));
buffer.replace(ret).unwrap();
}
#[cfg(feature="ditherpunk")]
Some(Opcode::RenderTile) => {
let buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
let mut obj = buffer.to_original::<GamTile, _>().unwrap();
log::debug!("RenderTile {:?}", obj);
if let Some(canvas) = canvases.get_mut(&obj.canvas) {
// first, figure out if we should even be drawing to this canvas.
log::debug!("drawable {} onscreen {} state{:?} for canvas {:?}", canvas.is_drawable(), canvas.is_onscreen(), canvas.state(), canvas.gid());
if canvas.is_drawable() && canvas.is_onscreen() {
obj.tile.translate(canvas.clip_rect().tl);
obj.tile.translate(canvas.pan_offset());
log::trace!("drawing tile {:?}", obj.tile);
gfx.draw_tile_clipped(
obj.tile,
canvas.clip_rect(),
).expect("couldn't draw bitmap");
canvas.do_drawn().expect("couldn't set canvas to drawn");
} else {
log::info!("attempt to draw Object on non-drawable canvas. Not fatal, but request ignored: {:?}", obj);
}
} else {
info!("bogus GID in Object, not doing anything in response to draw request.");
}
log::trace!("leaving RenderTile");
}
Some(Opcode::RenderObject) => {
let buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
let obj = buffer.to_original::<GamObject, _>().unwrap();
@ -346,16 +371,6 @@ fn main() -> ! {
canvas.clip_rect(),
).expect("couldn't draw rounded rectangle");
}
#[cfg(feature="ditherpunk")]
GamObjectType::Tile(mut tile) => {
log::info!("drawing tile {:?}", tile);
tile.translate(canvas.clip_rect().tl);
tile.translate(canvas.pan_offset());
gfx.draw_tile_clipped(
tile,
canvas.clip_rect(),
).expect("couldn't draw bitmap");
}
}
canvas.do_drawn().expect("couldn't set canvas to drawn");
} else {
@ -396,12 +411,6 @@ fn main() -> ! {
rr.translate(canvas.pan_offset());
obj_list.push(ClipObjectType::RoundRect(rr), canvas.clip_rect()).unwrap();
},
#[cfg(feature="ditherpunk")]
GamObjectType::Tile(mut tile) => {
tile.translate(canvas.clip_rect().tl);
tile.translate(canvas.pan_offset());
obj_list.push(ClipObjectType::Tile(tile), canvas.clip_rect()).unwrap();
}
}
} else {
break;