use { crate::{ client::{Client, ClientError}, gfx_api::GfxContext, leaks::Tracker, object::{Object, Version}, utils::errorfmt::ErrorFmt, wire::{JayRenderCtxId, jay_render_ctx::*}, }, std::rc::Rc, thiserror::Error, }; pub const FORMATS_SINCE: Version = Version(7); pub const WRITE_MODIFIER_2_SINCE: Version = Version(9); pub struct JayRenderCtx { pub id: JayRenderCtxId, pub client: Rc, pub tracker: Tracker, pub version: Version, } impl JayRenderCtx { pub fn send_render_ctx(&self, ctx: Option>) { let mut fd = None; if let Some(ctx) = ctx { if self.version >= FORMATS_SINCE { for format in ctx.formats().values() { self.client.event(Format { self_id: self.id, format: format.format.drm, }); for (modifier, gwm) in &format.write_modifiers { if self.version >= WRITE_MODIFIER_2_SINCE { self.client.event(WriteModifier2 { self_id: self.id, format: format.format.drm, modifier: *modifier, needs_render_usage: gwm.needs_render_usage as _, }); } else { self.client.event(WriteModifier { self_id: self.id, format: format.format.drm, modifier: *modifier, }); } } for modifier in &format.read_modifiers { self.client.event(ReadModifier { self_id: self.id, format: format.format.drm, modifier: *modifier, }); } } } let allocator = ctx.allocator(); match allocator.drm() { Some(drm) => match drm.dup_render() { Ok(d) => fd = Some(d.fd().clone()), Err(e) => { log::error!("Could not dup drm fd: {}", ErrorFmt(e)); } }, None => { log::error!("Allocator does not have a DRM device"); } } } match fd { Some(fd) => self.client.event(Device { self_id: self.id, fd, }), _ => self.client.event(NoDevice { self_id: self.id }), } } fn remove_from_state(&self) { self.client .state .render_ctx_watchers .remove(&(self.client.id, self.id)); } } impl JayRenderCtxRequestHandler for JayRenderCtx { type Error = JayRenderCtxError; fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.remove_from_state(); self.client.remove_obj(self)?; Ok(()) } } object_base! { self = JayRenderCtx; version = Version(1); } impl Object for JayRenderCtx { fn break_loops(&self) { self.remove_from_state(); } } simple_add_obj!(JayRenderCtx); #[derive(Debug, Error)] pub enum JayRenderCtxError { #[error(transparent)] ClientError(Box), } efrom!(JayRenderCtxError, ClientError);