Skip to content

Commit

Permalink
render: hide graphics API behind traits
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Oct 22, 2023
1 parent 7ebf05d commit b316611
Show file tree
Hide file tree
Showing 39 changed files with 596 additions and 242 deletions.
4 changes: 2 additions & 2 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use {
crate::{
async_engine::SpawnedFuture,
fixed::Fixed,
gfx_apis::gl::Framebuffer,
gfx_api::GfxFramebuffer,
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
video::drm::{ConnectorType, DrmError, DrmVersion},
},
Expand Down Expand Up @@ -95,7 +95,7 @@ pub enum ConnectorEvent {

pub trait HardwareCursor: Debug {
fn set_enabled(&self, enabled: bool);
fn get_buffer(&self) -> Rc<Framebuffer>;
fn get_buffer(&self) -> Rc<dyn GfxFramebuffer>;
fn set_position(&self, x: i32, y: i32);
fn swap_buffer(&self);
fn commit(&self);
Expand Down
16 changes: 8 additions & 8 deletions src/backends/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
},
backends::metal::video::{MetalDrmDeviceData, MetalRenderContext, PendingDrmDevice},
dbus::{DbusError, SignalHandler},
gfx_apis::gl::RenderError,
gfx_api::GfxError,
libinput::{
consts::{
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
Expand Down Expand Up @@ -75,7 +75,7 @@ pub enum MetalError {
#[error("Could not update the drm properties")]
UpdateProperties(#[source] DrmError),
#[error("Could not create a render context")]
CreateRenderContex(#[source] RenderError),
CreateRenderContex(#[source] GfxError),
#[error("Cannot initialize connector because no CRTC is available")]
NoCrtcForConnector,
#[error("Cannot initialize connector because no primary plane is available")]
Expand All @@ -86,12 +86,12 @@ pub enum MetalError {
ScanoutBuffer(#[source] GbmError),
#[error("addfb2 failed")]
Framebuffer(#[source] DrmError),
#[error("Could not import a framebuffer into EGL")]
ImportFb(#[source] RenderError),
#[error("Could not import a texture into EGL")]
ImportTexture(#[source] RenderError),
#[error("Could not import an image into EGL")]
ImportImage(#[source] RenderError),
#[error("Could not import a framebuffer into the graphics API")]
ImportFb(#[source] GfxError),
#[error("Could not import a texture into the graphics API")]
ImportTexture(#[source] GfxError),
#[error("Could not import an image into the graphics API")]
ImportImage(#[source] GfxError),
#[error("Could not perform modeset")]
Modeset(#[source] DrmError),
#[error("Could not enable atomic modesetting")]
Expand Down
43 changes: 22 additions & 21 deletions src/backends/metal/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use {
backends::metal::{MetalBackend, MetalError},
edid::Descriptor,
format::{Format, ARGB8888, XRGB8888},
gfx_apis::gl::{Framebuffer, RenderContext, Texture},
gfx_api::{GfxContext, GfxFramebuffer, GfxTexture},
gfx_apis::create_gfx_context,
ifs::wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC},
renderer::RenderResult,
state::State,
Expand Down Expand Up @@ -52,7 +53,7 @@ pub struct PendingDrmDevice {
#[derive(Debug)]
pub struct MetalRenderContext {
pub dev_id: DrmDeviceId,
pub egl: Rc<RenderContext>,
pub gfx: Rc<dyn GfxContext>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -214,7 +215,7 @@ impl HardwareCursor for MetalHardwareCursor {
}
}

fn get_buffer(&self) -> Rc<Framebuffer> {
fn get_buffer(&self) -> Rc<dyn GfxFramebuffer> {
let buffer = (self.connector.cursor_front_buffer.get() + 1) % 2;
self.cursor_buffers[buffer].render_fb()
}
Expand Down Expand Up @@ -375,7 +376,7 @@ impl MetalConnector {
fr.send_done();
let _ = fr.client.remove_obj(&*fr);
}
node.perform_screencopies(&render_fb, &buffer.render_tex);
node.perform_screencopies(&*render_fb, &buffer.render_tex);
}
changes.change_object(plane.id, |c| {
c.change(plane.fb_id, buffer.drm.id().0 as _);
Expand Down Expand Up @@ -883,9 +884,9 @@ impl MetalBackend {
None => return false,
};
if let Some(r) = ctx
.egl
.gfx
.reset_status()
.or_else(|| dev.ctx.egl.reset_status())
.or_else(|| dev.ctx.gfx.reset_status())
{
fatal!("EGL context has been reset: {:?}", r);
}
Expand Down Expand Up @@ -1090,13 +1091,13 @@ impl MetalBackend {
}
}

let egl = match RenderContext::from_drm_device(master) {
Ok(r) => Rc::new(r),
let gfx = match create_gfx_context(master) {
Ok(r) => r,
Err(e) => return Err(MetalError::CreateRenderContex(e)),
};
let ctx = Rc::new(MetalRenderContext {
dev_id: pending.id,
egl,
gfx,
});

let gbm = match GbmDevice::new(master) {
Expand Down Expand Up @@ -1421,7 +1422,7 @@ impl MetalBackend {
return true;
}
}
self.state.set_render_ctx(Some(&dev.ctx.egl));
self.state.set_render_ctx(Some(dev.ctx.gfx.clone()));
self.ctx.set(Some(dev.ctx.clone()));
let mut preserve = Preserve::default();
for dev in self.device_holder.drm_devices.lock().values() {
Expand Down Expand Up @@ -1601,11 +1602,11 @@ impl MetalBackend {
Ok(fb) => Rc::new(fb),
Err(e) => return Err(MetalError::Framebuffer(e)),
};
let dev_img = match dev.ctx.egl.dmabuf_img(dev_bo.dmabuf()) {
let dev_img = match dev.ctx.gfx.clone().dmabuf_img(dev_bo.dmabuf()) {
Ok(img) => img,
Err(e) => return Err(MetalError::ImportImage(e)),
};
let dev_fb = match dev_img.to_framebuffer() {
let dev_fb = match dev_img.clone().to_framebuffer() {
Ok(fb) => fb,
Err(e) => return Err(MetalError::ImportFb(e)),
};
Expand All @@ -1619,16 +1620,16 @@ impl MetalBackend {
} else {
// Create a _bridge_ BO in the render device
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
let render_bo = render_ctx.egl.gbm.create_bo(width, height, format, usage);
let render_bo = render_ctx.gfx.gbm().create_bo(width, height, format, usage);
let render_bo = match render_bo {
Ok(b) => b,
Err(e) => return Err(MetalError::ScanoutBuffer(e)),
};
let render_img = match render_ctx.egl.dmabuf_img(render_bo.dmabuf()) {
let render_img = match render_ctx.gfx.clone().dmabuf_img(render_bo.dmabuf()) {
Ok(img) => img,
Err(e) => return Err(MetalError::ImportImage(e)),
};
let render_fb = match render_img.to_framebuffer() {
let render_fb = match render_img.clone().to_framebuffer() {
Ok(fb) => fb,
Err(e) => return Err(MetalError::ImportFb(e)),
};
Expand All @@ -1639,7 +1640,7 @@ impl MetalBackend {
};

// Import the bridge BO into the current device
let dev_img = match dev.ctx.egl.dmabuf_img(render_bo.dmabuf()) {
let dev_img = match dev.ctx.gfx.clone().dmabuf_img(render_bo.dmabuf()) {
Ok(img) => img,
Err(e) => return Err(MetalError::ImportImage(e)),
};
Expand Down Expand Up @@ -1833,20 +1834,20 @@ pub struct RenderBuffer {
drm: Rc<DrmFramebuffer>,
// ctx = dev
// buffer location = dev
dev_fb: Rc<Framebuffer>,
dev_fb: Rc<dyn GfxFramebuffer>,
// ctx = dev
// buffer location = render
dev_tex: Option<Rc<Texture>>,
dev_tex: Option<Rc<dyn GfxTexture>>,
// ctx = render
// buffer location = render
render_tex: Rc<Texture>,
render_tex: Rc<dyn GfxTexture>,
// ctx = render
// buffer location = render
render_fb: Option<Rc<Framebuffer>>,
render_fb: Option<Rc<dyn GfxFramebuffer>>,
}

impl RenderBuffer {
fn render_fb(&self) -> Rc<Framebuffer> {
fn render_fb(&self) -> Rc<dyn GfxFramebuffer> {
self.render_fb
.clone()
.unwrap_or_else(|| self.dev_fb.clone())
Expand Down
37 changes: 19 additions & 18 deletions src/backends/x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use {
},
fixed::Fixed,
format::XRGB8888,
gfx_apis::gl::{Framebuffer, RenderContext, RenderError, Texture},
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
gfx_apis::create_gfx_context,
renderer::RenderResult,
state::State,
time::now_usec,
Expand Down Expand Up @@ -89,14 +90,14 @@ pub enum XBackendError {
GbmError(#[from] GbmError),
#[error("Could not import a dma-buf")]
ImportBuffer(#[source] XconError),
#[error("Could not create an EGL context")]
CreateEgl(#[source] RenderError),
#[error("Could not create an EGL image from a dma-buf")]
CreateImage(#[source] RenderError),
#[error("Could not create a framebuffer from an EGL image")]
CreateFramebuffer(#[source] RenderError),
#[error("Could not create a texture from an EGL image")]
CreateTexture(#[source] RenderError),
#[error("Could not create a graphics API context")]
CreateEgl(#[source] GfxError),
#[error("Could not create an graphics API image from a dma-buf")]
CreateImage(#[source] GfxError),
#[error("Could not create a framebuffer from a graphics API image")]
CreateFramebuffer(#[source] GfxError),
#[error("Could not create a texture from an graphics API image")]
CreateTexture(#[source] GfxError),
#[error("Could not select input events")]
CannotSelectInputEvents(#[source] XconError),
#[error("Could not select present events")]
Expand Down Expand Up @@ -178,8 +179,8 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
Err(e) => return Err(XBackendError::DrmDeviceFstat(e)),
};
let gbm = GbmDevice::new(&drm)?;
let ctx = match RenderContext::from_drm_device(&drm) {
Ok(r) => Rc::new(r),
let ctx = match create_gfx_context(&drm) {
Ok(r) => r,
Err(e) => return Err(XBackendError::CreateEgl(e)),
};
let cursor = {
Expand Down Expand Up @@ -266,7 +267,7 @@ pub struct XBackend {
outputs: CopyHashMap<u32, Rc<XOutput>>,
seats: CopyHashMap<u16, Rc<XSeat>>,
mouse_seats: CopyHashMap<u16, Rc<XSeat>>,
ctx: Rc<RenderContext>,
ctx: Rc<dyn GfxContext>,
gbm: GbmDevice,
cursor: u32,
root: u32,
Expand All @@ -288,7 +289,7 @@ impl XBackend {
.eng
.spawn2(Phase::Present, self.clone().present_handler());

self.state.set_render_ctx(Some(&self.ctx));
self.state.set_render_ctx(Some(self.ctx.clone()));
self.state
.backend_events
.push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice {
Expand Down Expand Up @@ -388,11 +389,11 @@ impl XBackend {
assert!(dma.planes.len() == 1);
let plane = dma.planes.first().unwrap();
let size = plane.stride * dma.height as u32;
let img = match self.ctx.dmabuf_img(dma) {
let img = match self.ctx.clone().dmabuf_img(dma) {
Ok(f) => f,
Err(e) => return Err(XBackendError::CreateImage(e)),
};
let fb = match img.to_framebuffer() {
let fb = match img.clone().to_framebuffer() {
Ok(f) => f,
Err(e) => return Err(XBackendError::CreateFramebuffer(e)),
};
Expand Down Expand Up @@ -735,7 +736,7 @@ impl XBackend {
fr.send_done();
let _ = fr.client.remove_obj(&*fr);
}
node.perform_screencopies(&fb, &image.tex.get());
node.perform_screencopies(&*fb, &image.tex.get());
}

let pp = PresentPixmap {
Expand Down Expand Up @@ -989,8 +990,8 @@ struct XOutput {

struct XImage {
pixmap: Cell<u32>,
fb: CloneCell<Rc<Framebuffer>>,
tex: CloneCell<Rc<Texture>>,
fb: CloneCell<Rc<dyn GfxFramebuffer>>,
tex: CloneCell<Rc<dyn GfxTexture>>,
idle: Cell<bool>,
render_on_idle: Cell<bool>,
last_serial: Cell<u32>,
Expand Down
4 changes: 0 additions & 4 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use {
config::ConfigProxy,
dbus::Dbus,
forker,
gfx_apis::gl::{self, RenderError},
globals::Globals,
ifs::{wl_output::WlOutputGlobal, wl_surface::NoneSurfaceExt},
io_uring::{IoUring, IoUringError},
Expand Down Expand Up @@ -86,8 +85,6 @@ pub enum CompositorError {
ClientmemError(#[from] ClientMemError),
#[error("The timer subsystem caused an error")]
WheelError(#[from] WheelError),
#[error("The render backend caused an error")]
RenderError(#[from] RenderError),
#[error("Could not create an io-uring")]
IoUringError(#[from] IoUringError),
}
Expand All @@ -112,7 +109,6 @@ fn start_compositor2(
log::info!("pid = {}", uapi::getpid());
init_fd_limit();
leaks::init();
gl::init()?;
clientmem::init()?;
let xkb_ctx = XkbContext::new().unwrap();
let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap();
Expand Down
16 changes: 9 additions & 7 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use {
crate::{
fixed::Fixed,
format::ARGB8888,
gfx_apis::gl::{RenderContext, RenderError, Texture},
gfx_api::{GfxContext, GfxError, GfxTexture},
rect::Rect,
renderer::Renderer,
scale::Scale,
Expand Down Expand Up @@ -87,7 +87,7 @@ pub enum KnownCursor {
}

impl ServerCursors {
pub fn load(ctx: &Rc<RenderContext>, state: &State) -> Result<Option<Self>, CursorError> {
pub fn load(ctx: &Rc<dyn GfxContext>, state: &State) -> Result<Option<Self>, CursorError> {
let paths = find_cursor_paths();
log::debug!("Trying to load cursors from paths {:?}", paths);
let sizes = state.cursor_sizes.to_vec();
Expand Down Expand Up @@ -135,7 +135,7 @@ impl ServerCursorTemplate {
scales: &[Scale],
sizes: &[u32],
paths: &[BString],
ctx: &Rc<RenderContext>,
ctx: &Rc<dyn GfxContext>,
) -> Result<Self, CursorError> {
match open_cursor(name, theme, scales, sizes, paths) {
Ok(cs) => {
Expand Down Expand Up @@ -215,7 +215,7 @@ impl ServerCursorTemplate {

struct CursorImageScaled {
extents: Rect,
tex: Rc<Texture>,
tex: Rc<dyn GfxTexture>,
}

struct CursorImage {
Expand All @@ -230,7 +230,7 @@ struct InstantiatedCursorImage {

impl CursorImageScaled {
fn from_bytes(
ctx: &Rc<RenderContext>,
ctx: &Rc<dyn GfxContext>,
data: &[Cell<u8>],
width: i32,
height: i32,
Expand All @@ -239,7 +239,9 @@ impl CursorImageScaled {
) -> Result<Rc<Self>, CursorError> {
Ok(Rc::new(Self {
extents: Rect::new_sized(-xhot, -yhot, width, height).unwrap(),
tex: ctx.shmem_texture(data, ARGB8888, width, height, width * 4)?,
tex: ctx
.clone()
.shmem_texture(data, ARGB8888, width, height, width * 4)?,
}))
}
}
Expand Down Expand Up @@ -536,7 +538,7 @@ pub enum CursorError {
#[error("The requested cursor could not be found")]
NotFound,
#[error("Could not import the cursor as a texture")]
ImportError(#[from] RenderError),
ImportError(#[from] GfxError),
}

#[derive(Default, Clone)]
Expand Down
Loading

0 comments on commit b316611

Please sign in to comment.