Skip to content

Commit

Permalink
Add graphics crate
Browse files Browse the repository at this point in the history
Signed-off-by: Klimenty Tsoutsman <klim@tsoutsman.com>
  • Loading branch information
tsoutsman committed Nov 8, 2023
1 parent a6aeee7 commit cf6440e
Show file tree
Hide file tree
Showing 9 changed files with 399 additions and 99 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions kernel/compositor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ async_channel = { path = "../async_channel" }
dreadnought = { path = "../dreadnought" }
event_types = { path = "../event_types" }
futures = { version = "0.3.28", default-features = false, features = ["async-await"] }
graphics = { path = "../graphics" }
hashbrown = "0.11.2"
log = "0.4.8"
memory = { path = "../memory" }
Expand Down
108 changes: 12 additions & 96 deletions kernel/compositor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,31 @@ extern crate alloc;

mod window;

use alloc::{boxed::Box, sync::Arc};
use alloc::sync::Arc;
use core::sync::atomic::{AtomicUsize, Ordering};

use async_channel::Channel;
use futures::StreamExt;
use graphics::{AlphaPixel, Framebuffer, GraphicsDriver, Pixel, Rectangle};
use hashbrown::HashMap;
use log::error;
use memory::{BorrowedSliceMappedPages, Mutable};
use sync_spin::Mutex;
pub use window::Window;
use zerocopy::FromBytes;

static COMPOSITOR: Option<Channel<Request>> = None;

static DRIVER: Mutex<Option<Box<dyn GraphicsDriver>>> = Mutex::new(None);
static DRIVER: Mutex<Option<GraphicsDriver<AlphaPixel>>> = Mutex::new(None);

pub fn init<T>(driver: T) -> Result<Channels, &'static str>
where
T: GraphicsDriver + 'static,
T: Into<GraphicsDriver<AlphaPixel>>,
{
let mut maybe_driver = DRIVER.lock();
assert!(
maybe_driver.is_none(),
"initialised compositor multiple times"
);
*maybe_driver = Some(Box::new(driver));
*maybe_driver = Some(driver.into());

let channels = Channels::new();
let cloned = channels.clone();
Expand Down Expand Up @@ -73,117 +72,32 @@ trait Draw {
fn set_size(&mut self, width: usize, height: usize);
}

#[derive(Clone, Copy, PartialEq, Debug, Hash)]
pub struct Coordinates {
pub x: usize,
pub y: usize,
}

#[derive(Clone)]
pub struct Rectangle {
pub coordinates: Coordinates,
pub width: usize,
pub height: usize,
}

pub struct Framebuffer<P>
where
P: Pixel,
{
buffer: BorrowedSliceMappedPages<P, Mutable>,
stride: usize,
width: usize,
height: usize,
}

#[derive(Clone)]
pub enum Event {
/// The compositor released the framebuffer.
Release,
}

impl<P> Framebuffer<P>
where
P: Pixel,
{
pub fn rows(&self) -> impl Iterator<Item = &[P]> {
self.buffer.chunks(self.stride)
}

pub fn rows_mut(&mut self) -> impl Iterator<Item = &mut [P]> {
self.buffer.chunks_mut(self.stride)
}
}

// TODO: Should it be sealed?
pub trait Pixel: private::Sealed + FromBytes {}

mod private {
pub trait Sealed {}
}

pub trait GraphicsDriver: Send + Sync {
fn back_mut(&mut self) -> &mut Framebuffer<AlphaPixel>;

// fn swap(rectangles: &[Rectangle]);
fn swap(&self);

fn post_swap(&self);
}

fn redraw(window: &window::Inner, _dirty: Rectangle) {
fn redraw(window: &window::Inner, dirty: Rectangle) {
let mut locked = DRIVER.lock();
let driver = locked.as_mut().unwrap();
let framebuffer = driver.back_mut();
let framebuffer = driver.back();

// TODO: Take into account dirty rectangle.

for (i, row) in window.framebuffer.rows().enumerate() {
let start = (window.coordinates.y + i) * framebuffer.stride;
let start = (window.coordinates.y + i) * framebuffer.stride();
let end = start + row.len();
framebuffer.buffer[start..end].clone_from_slice(row);
framebuffer[start..end].clone_from_slice(row);
}

driver.swap();
driver.post_swap();
driver.swap(&[dirty]);
}

pub trait SingleBufferGraphicsDriver {
fn write();
}

pub struct SimpleDriver {
inner: Framebuffer<AlphaPixel>,
}

impl SimpleDriver {
pub unsafe fn new(physical_address: usize, width: usize, height: usize) {
todo!();
}
}

impl GraphicsDriver for SimpleDriver {
fn back_mut(&mut self) -> &mut Framebuffer<AlphaPixel> {
&mut self.inner
}

fn swap(&self) {}

fn post_swap(&self) {}
}

pub trait DoubleBufferGraphicsDriver {
fn write();
fn swap();
}

#[derive(Clone, FromBytes)]
pub struct AlphaPixel {}

impl private::Sealed for AlphaPixel {}

impl Pixel for AlphaPixel {}

#[derive(Clone)]
pub struct Channels {
// FIXME: Event type
Expand Down Expand Up @@ -217,6 +131,8 @@ pub fn window() -> Window {

async fn compositor_loop(mut channels: Channels) {
loop {
// TODO: Compute overlap.

// The select macro is not available in no_std.
futures::select_biased!(
event = channels.window.next() => {
Expand Down
5 changes: 2 additions & 3 deletions kernel/compositor/src/window.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use alloc::sync::Arc;

use async_channel::Channel;
use graphics::{AlphaPixel, Coordinates, Framebuffer, Rectangle};
use sync_spin::Mutex;

use crate::{
AlphaPixel, Coordinates, Event, Framebuffer, Rectangle, Request, RequestType, COMPOSITOR,
};
use crate::{Event, Request, RequestType, COMPOSITOR};

pub struct Window {
pub(crate) id: usize,
Expand Down
9 changes: 9 additions & 0 deletions kernel/graphics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "graphics"
version = "0.1.0"
edition = "2021"

[dependencies]
memory = { path = "../memory" }
# TODO: Upgrade to 0.7.25
zerocopy = "0.5.0"
Loading

0 comments on commit cf6440e

Please sign in to comment.