render: hide graphics API behind traits
This commit is contained in:
parent
d650b3375d
commit
24e410a5b5
40 changed files with 601 additions and 246 deletions
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue