1
0
Fork 0
forked from wry/wry

render: hide graphics API behind traits

This commit is contained in:
Julian Orth 2023-10-22 20:00:32 +02:00
parent d650b3375d
commit 24e410a5b5
40 changed files with 601 additions and 246 deletions

View file

@ -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,
@ -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")]
@ -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")]

View file

@ -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,
@ -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)]
@ -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()
}
@ -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 _);
@ -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);
}
@ -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) {
@ -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() {
@ -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)),
};
@ -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)),
};
@ -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)),
};
@ -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())

View file

@ -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,
@ -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")]
@ -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 = {
@ -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,
@ -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 {
@ -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)),
};
@ -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 {
@ -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>,