use crate::format::formats;
use crate::gfx_api::GfxFormat;
use crate::gfx_api::GfxWriteModifier;
use crate::ifs::jay_render_ctx::FORMATS_SINCE;
use crate::object::Version;
use crate::utils::bhash::BHashMap;
use crate::utils::clonecell::CloneCell;
use crate::video::Modifier;
use crate::wire::JayRenderCtxId;
use crate::wire::jay_render_ctx::*;
use crate::wl_usr::UsrCon;
use crate::wl_usr::usr_object::UsrObject;
use std::cell::RefCell;
use std::convert::Infallible;
use std::rc::Rc;
use uapi::OwnedFd;
pub struct UsrJayRenderCtx {
pub id: JayRenderCtxId,
pub con: Rc<UsrCon>,
pub owner: CloneCell<Option<Rc<dyn UsrJayRenderCtxOwner>>>,
pub version: Version,
pub formats: RefCell<BHashMap<u32, GfxFormat>>,
}
pub trait UsrJayRenderCtxOwner {
fn no_device(&self) {}
fn device(&self, fd: Rc<OwnedFd>, server_formats: Option<BHashMap<u32, GfxFormat>>) {
let _ = fd;
let _ = server_formats;
}
}
impl UsrJayRenderCtx {
fn add_write_modifier(&self, format: u32, modifier: Modifier, needs_render_usage: bool) {
if let Some(format) = self.formats.borrow_mut().get_mut(&format) {
format
.write_modifiers
.insert(modifier, GfxWriteModifier { needs_render_usage });
}
}
}
impl JayRenderCtxEventHandler for UsrJayRenderCtx {
type Error = Infallible;
fn no_device(&self, _ev: NoDevice, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.formats.take();
if let Some(owner) = self.owner.get() {
owner.no_device();
}
Ok(())
}
fn device(&self, ev: Device, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let formats = self.formats.take();
let formats = (self.version >= FORMATS_SINCE).then_some(formats);
if let Some(owner) = self.owner.get() {
owner.device(ev.fd, formats);
}
Ok(())
}
fn read_modifier(&self, ev: ReadModifier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(format) = self.formats.borrow_mut().get_mut(&ev.format) {
format.read_modifiers.insert(ev.modifier);
}
Ok(())
}
fn write_modifier(&self, ev: WriteModifier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.add_write_modifier(ev.format, ev.modifier, true);
Ok(())
}
fn format(&self, ev: Format, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(format) = formats().get(&ev.format) {
self.formats.borrow_mut().insert(
ev.format,
GfxFormat {
format,
read_modifiers: Default::default(),
write_modifiers: Default::default(),
supports_shm: false,
},
);
}
Ok(())
}
fn write_modifier2(&self, ev: WriteModifier2, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.add_write_modifier(ev.format, ev.modifier, ev.needs_render_usage);
Ok(())
}
}
usr_object_base! {
self = UsrJayRenderCtx = JayRenderCtx;
version = self.version;
}
impl UsrObject for UsrJayRenderCtx {
fn destroy(&self) {
self.con.request(Destroy { self_id: self.id });
}
fn break_loops(&self) {
self.owner.take();
}
}