mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 01:16:26 +04:00
user: bugfix #148: Optimize GUI
User should call sys_framebuffer_flush only once after the modification on the framebuffer has been completed. This commit also renames some gui apps.
This commit is contained in:
parent
868f00bec1
commit
81d10f2f78
82
user/src/bin/gui_move.rs
Normal file
82
user/src/bin/gui_move.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate user_lib;
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use user_lib::console::getchar;
|
||||||
|
use user_lib::{Display, VIRTGPU_XRES, VIRTGPU_YRES};
|
||||||
|
|
||||||
|
use embedded_graphics::pixelcolor::Rgb888;
|
||||||
|
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};
|
||||||
|
use embedded_graphics::primitives::Primitive;
|
||||||
|
use embedded_graphics::primitives::{PrimitiveStyle, Rectangle};
|
||||||
|
use embedded_graphics::draw_target::DrawTarget;
|
||||||
|
|
||||||
|
const INIT_X: i32 = 640;
|
||||||
|
const INIT_Y: i32 = 400;
|
||||||
|
const RECT_SIZE: u32 = 40;
|
||||||
|
|
||||||
|
pub struct DrawingBoard {
|
||||||
|
disp: Display,
|
||||||
|
latest_pos: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawingBoard {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
disp: Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES)),
|
||||||
|
latest_pos: Point::new(INIT_X, INIT_Y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn paint(&mut self) {
|
||||||
|
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(Rgb888::WHITE, 1))
|
||||||
|
.draw(&mut self.disp)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
fn unpaint(&mut self) {
|
||||||
|
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(Rgb888::BLACK, 1))
|
||||||
|
.draw(&mut self.disp)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
pub fn move_rect(&mut self, dx: i32, dy: i32) {
|
||||||
|
let new_x = self.latest_pos.x + dx;
|
||||||
|
let new_y = self.latest_pos.y + dy;
|
||||||
|
let r = (RECT_SIZE / 2) as i32;
|
||||||
|
if new_x > r && new_x + r < (VIRTGPU_XRES as i32) && new_y > r && new_y + r < (VIRTGPU_YRES as i32) {
|
||||||
|
self.unpaint();
|
||||||
|
self.latest_pos.x = new_x;
|
||||||
|
self.latest_pos.y = new_y;
|
||||||
|
self.paint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const LF: u8 = 0x0au8;
|
||||||
|
const CR: u8 = 0x0du8;
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main() -> i32 {
|
||||||
|
let mut board = DrawingBoard::new();
|
||||||
|
let _ = board.disp.clear(Rgb888::BLACK).unwrap();
|
||||||
|
board.disp.flush();
|
||||||
|
loop {
|
||||||
|
let c = getchar();
|
||||||
|
if c == LF || c == CR {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut moved = true;
|
||||||
|
match c {
|
||||||
|
b'w' => board.move_rect(0, -10),
|
||||||
|
b'a' => board.move_rect(-10, 0),
|
||||||
|
b's' => board.move_rect(0, 10),
|
||||||
|
b'd' => board.move_rect(10, 0),
|
||||||
|
_ => moved = false,
|
||||||
|
}
|
||||||
|
if moved {
|
||||||
|
board.disp.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
@ -44,18 +44,6 @@ impl DrawingBoard {
|
|||||||
.draw(&mut self.disp)
|
.draw(&mut self.disp)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
fn unpaint(&mut self) {
|
|
||||||
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Rgb888::BLACK, 10))
|
|
||||||
.draw(&mut self.disp)
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
pub fn move_rect(&mut self, dx: i32, dy: i32) {
|
|
||||||
self.unpaint();
|
|
||||||
self.latest_pos.x += dx;
|
|
||||||
self.latest_pos.y += dy;
|
|
||||||
self.paint();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -64,8 +52,8 @@ pub fn main() -> i32 {
|
|||||||
let _ = board.disp.clear(Rgb888::BLACK).unwrap();
|
let _ = board.disp.clear(Rgb888::BLACK).unwrap();
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
board.latest_pos.x += RECT_SIZE as i32 + 20;
|
board.latest_pos.x += RECT_SIZE as i32 + 20;
|
||||||
//board.latest_pos.y += i;
|
|
||||||
board.paint();
|
board.paint();
|
||||||
}
|
}
|
||||||
|
board.disp.flush();
|
||||||
0
|
0
|
||||||
}
|
}
|
@ -328,7 +328,7 @@ const CR: u8 = 0x0du8;
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn main() -> i32 {
|
pub fn main() -> i32 {
|
||||||
let mut disp = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES));
|
let mut disp = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES));
|
||||||
let mut game = SnakeGame::<20, Rgb888>::new(1280, 800, 20, 20, Rgb888::RED, Rgb888::YELLOW, 50);
|
let mut game = SnakeGame::<20, Rgb888>::new(1280, 800, 20, 20, Rgb888::RED, Rgb888::YELLOW, 200);
|
||||||
let _ = disp.clear(Rgb888::BLACK).unwrap();
|
let _ = disp.clear(Rgb888::BLACK).unwrap();
|
||||||
loop {
|
loop {
|
||||||
if key_pressed() {
|
if key_pressed() {
|
||||||
@ -345,7 +345,8 @@ pub fn main() -> i32 {
|
|||||||
}
|
}
|
||||||
let _ = disp.clear(Rgb888::BLACK).unwrap();
|
let _ = disp.clear(Rgb888::BLACK).unwrap();
|
||||||
game.draw(&mut disp);
|
game.draw(&mut disp);
|
||||||
sleep(10);
|
disp.flush();
|
||||||
|
sleep(40);
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -19,5 +19,6 @@ pub fn main() -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
disp.flush();
|
||||||
0
|
0
|
||||||
}
|
}
|
@ -1,125 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
#![no_main]
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate user_lib;
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
use user_lib::console::getchar;
|
|
||||||
use user_lib::{framebuffer, framebuffer_flush};
|
|
||||||
|
|
||||||
use embedded_graphics::pixelcolor::Rgb888;
|
|
||||||
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};
|
|
||||||
use embedded_graphics::primitives::Primitive;
|
|
||||||
use embedded_graphics::primitives::{PrimitiveStyle, Rectangle};
|
|
||||||
use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions};
|
|
||||||
|
|
||||||
pub const VIRTGPU_XRES: usize = 1280;
|
|
||||||
pub const VIRTGPU_YRES: usize = 800;
|
|
||||||
pub const VIRTGPU_LEN: usize = VIRTGPU_XRES * VIRTGPU_YRES * 4;
|
|
||||||
|
|
||||||
const INIT_X: i32 = 640;
|
|
||||||
const INIT_Y: i32 = 400;
|
|
||||||
const RECT_SIZE: u32 = 40;
|
|
||||||
|
|
||||||
pub struct Display {
|
|
||||||
pub size: Size,
|
|
||||||
pub point: Point,
|
|
||||||
//pub fb: Arc<&'static mut [u8]>,
|
|
||||||
pub fb: &'static mut [u8],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display {
|
|
||||||
pub fn new(size: Size, point: Point) -> Self {
|
|
||||||
let fb_ptr = framebuffer() as *mut u8;
|
|
||||||
println!(
|
|
||||||
"Hello world from user mode program! 0x{:X} , len {}",
|
|
||||||
fb_ptr as usize, VIRTGPU_LEN
|
|
||||||
);
|
|
||||||
let fb =
|
|
||||||
unsafe { core::slice::from_raw_parts_mut(fb_ptr as *mut u8, VIRTGPU_LEN as usize) };
|
|
||||||
Self { size, point, fb }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OriginDimensions for Display {
|
|
||||||
fn size(&self) -> Size {
|
|
||||||
self.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DrawTarget for Display {
|
|
||||||
type Color = Rgb888;
|
|
||||||
|
|
||||||
type Error = core::convert::Infallible;
|
|
||||||
|
|
||||||
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
|
|
||||||
{
|
|
||||||
pixels.into_iter().for_each(|px| {
|
|
||||||
let idx = ((self.point.y + px.0.y) * VIRTGPU_XRES as i32 + self.point.x + px.0.x)
|
|
||||||
as usize
|
|
||||||
* 4;
|
|
||||||
if idx + 2 >= self.fb.len() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.fb[idx] = px.1.b();
|
|
||||||
self.fb[idx + 1] = px.1.g();
|
|
||||||
self.fb[idx + 2] = px.1.r();
|
|
||||||
});
|
|
||||||
framebuffer_flush();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DrawingBoard {
|
|
||||||
disp: Display,
|
|
||||||
latest_pos: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DrawingBoard {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
disp: Display::new(Size::new(1280, 800), Point::new(0, 0)),
|
|
||||||
latest_pos: Point::new(INIT_X, INIT_Y),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn paint(&mut self) {
|
|
||||||
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Rgb888::WHITE, 1))
|
|
||||||
.draw(&mut self.disp)
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
fn unpaint(&mut self) {
|
|
||||||
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
|
||||||
.into_styled(PrimitiveStyle::with_stroke(Rgb888::BLACK, 1))
|
|
||||||
.draw(&mut self.disp)
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
pub fn move_rect(&mut self, dx: i32, dy: i32) {
|
|
||||||
self.unpaint();
|
|
||||||
self.latest_pos.x += dx;
|
|
||||||
self.latest_pos.y += dy;
|
|
||||||
self.paint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const LF: u8 = 0x0au8;
|
|
||||||
const CR: u8 = 0x0du8;
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn main() -> i32 {
|
|
||||||
// let fb_ptr = framebuffer() as *mut u8;
|
|
||||||
let mut board = DrawingBoard::new();
|
|
||||||
let _ = board.disp.clear(Rgb888::BLACK).unwrap();
|
|
||||||
for i in 0..20 {
|
|
||||||
let c = getchar();
|
|
||||||
if c == LF || c == CR {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
board.latest_pos.x += i;
|
|
||||||
board.latest_pos.y += i;
|
|
||||||
board.paint();
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
|
@ -32,6 +32,8 @@ impl Display {
|
|||||||
}
|
}
|
||||||
pub fn paint_on_framebuffer(&mut self, p: impl FnOnce(&mut [u8]) -> ()) {
|
pub fn paint_on_framebuffer(&mut self, p: impl FnOnce(&mut [u8]) -> ()) {
|
||||||
p(self.framebuffer());
|
p(self.framebuffer());
|
||||||
|
}
|
||||||
|
pub fn flush(&self) {
|
||||||
framebuffer_flush();
|
framebuffer_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +62,6 @@ impl DrawTarget for Display {
|
|||||||
self.fb[idx + 1] = px.1.g();
|
self.fb[idx + 1] = px.1.g();
|
||||||
self.fb[idx + 2] = px.1.r();
|
self.fb[idx + 2] = px.1.r();
|
||||||
});
|
});
|
||||||
framebuffer_flush();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user