From 53ca7b5b2a9900144eb340b6566cea09ccfefc9f Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 30 Jul 2022 11:18:53 +0200 Subject: [PATCH] wayland: add jay_render_ctx --- src/compositor.rs | 1 + src/ifs.rs | 1 + src/ifs/jay_compositor.rs | 24 ++++++++++- src/ifs/jay_render_ctx.rs | 86 +++++++++++++++++++++++++++++++++++++++ src/state.rs | 9 +++- wire/jay_compositor.txt | 4 ++ wire/jay_render_ctx.txt | 15 +++++++ 7 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 src/ifs/jay_render_ctx.rs create mode 100644 wire/jay_render_ctx.txt diff --git a/src/compositor.rs b/src/compositor.rs index 275e6d16..fff98dbb 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -195,6 +195,7 @@ fn start_compositor2( cursor_sizes: Default::default(), hardware_tick_cursor: Default::default(), testers: Default::default(), + render_ctx_watchers: Default::default(), }); state.tracker.register(ClientId::from_raw(0)); create_dummy_output(&state); diff --git a/src/ifs.rs b/src/ifs.rs index 57a16714..cec5d32c 100644 --- a/src/ifs.rs +++ b/src/ifs.rs @@ -6,6 +6,7 @@ pub mod jay_idle; pub mod jay_log_file; pub mod jay_output; pub mod jay_pointer; +pub mod jay_render_ctx; pub mod jay_screenshot; pub mod jay_seat_events; pub mod org_kde_kwin_server_decoration; diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 084c5839..de61fc39 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -5,7 +5,8 @@ use { globals::{Global, GlobalName}, ifs::{ jay_idle::JayIdle, jay_log_file::JayLogFile, jay_output::JayOutput, - jay_pointer::JayPointer, jay_screenshot::JayScreenshot, jay_seat_events::JaySeatEvents, + jay_pointer::JayPointer, jay_render_ctx::JayRenderCtx, jay_screenshot::JayScreenshot, + jay_seat_events::JaySeatEvents, }, leaks::Tracker, object::Object, @@ -260,6 +261,24 @@ impl JayCompositor { self.client.add_client_obj(&ctx)?; Ok(()) } + + fn get_render_ctx(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { + let req: GetRenderCtx = self.client.parse(self, parser)?; + let ctx = Rc::new(JayRenderCtx { + id: req.id, + client: self.client.clone(), + tracker: Default::default(), + }); + track!(self.client, ctx); + self.client.add_client_obj(&ctx)?; + self.client + .state + .render_ctx_watchers + .set((self.client.id, req.id), ctx.clone()); + let rctx = self.client.state.render_ctx.get(); + ctx.send_render_ctx(rctx.as_ref()); + Ok(()) + } } object_base! { @@ -278,11 +297,12 @@ object_base! { SEAT_EVENTS => seat_events, GET_OUTPUT => get_output, GET_POINTER => get_pointer, + GET_RENDER_CTX => get_render_ctx, } impl Object for JayCompositor { fn num_requests(&self) -> u32 { - GET_POINTER + 1 + GET_RENDER_CTX + 1 } } diff --git a/src/ifs/jay_render_ctx.rs b/src/ifs/jay_render_ctx.rs new file mode 100644 index 00000000..73e8374b --- /dev/null +++ b/src/ifs/jay_render_ctx.rs @@ -0,0 +1,86 @@ +use { + crate::{ + client::{Client, ClientError}, + leaks::Tracker, + object::Object, + render::RenderContext, + utils::{ + buffd::{MsgParser, MsgParserError}, + errorfmt::ErrorFmt, + }, + wire::{jay_render_ctx::*, JayRenderCtxId}, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct JayRenderCtx { + pub id: JayRenderCtxId, + pub client: Rc, + pub tracker: Tracker, +} + +impl JayRenderCtx { + pub fn send_render_ctx(&self, ctx: Option<&Rc>) { + let mut fd = None; + if let Some(ctx) = ctx { + match ctx.gbm.drm.dup_render() { + Ok(d) => fd = Some(d.fd().clone()), + Err(e) => { + log::error!("Could not dup drm fd: {}", ErrorFmt(e)); + } + } + } else { + self.client.event(NoDevice { self_id: self.id }); + } + match fd { + Some(fd) => self.client.event(Device { + self_id: self.id, + fd, + }), + _ => self.client.event(NoDevice { self_id: self.id }), + } + } + + fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRenderCtxError> { + let _req: Destroy = self.client.parse(self, parser)?; + self.remove_from_state(); + self.client.remove_obj(self)?; + Ok(()) + } + + fn remove_from_state(&self) { + self.client + .state + .render_ctx_watchers + .remove(&(self.client.id, self.id)); + } +} + +object_base! { + JayRenderCtx; + + DESTROY => destroy, +} + +impl Object for JayRenderCtx { + fn num_requests(&self) -> u32 { + DESTROY + 1 + } + + fn break_loops(&self) { + self.remove_from_state(); + } +} + +simple_add_obj!(JayRenderCtx); + +#[derive(Debug, Error)] +pub enum JayRenderCtxError { + #[error("Parsing failed")] + MsgParserError(Box), + #[error(transparent)] + ClientError(Box), +} +efrom!(JayRenderCtxError, MsgParserError); +efrom!(JayRenderCtxError, ClientError); diff --git a/src/state.rs b/src/state.rs index d2b249df..167fc5a2 100644 --- a/src/state.rs +++ b/src/state.rs @@ -17,6 +17,7 @@ use { globals::{Globals, GlobalsError, WaylandGlobal}, ifs::{ ext_session_lock_v1::ExtSessionLockV1, + jay_render_ctx::JayRenderCtx, jay_seat_events::JaySeatEvents, wl_drm::WlDrmGlobal, wl_seat::{SeatIds, WlSeatGlobal}, @@ -42,7 +43,7 @@ use { queue::AsyncQueue, refcounted::RefCounted, run_toplevel::RunToplevel, }, wheel::Wheel, - wire::JaySeatEventsId, + wire::{JayRenderCtxId, JaySeatEventsId}, xkbcommon::{XkbContext, XkbKeymap}, xwayland::{self, XWaylandEvent}, }, @@ -117,6 +118,7 @@ pub struct State { pub cursor_sizes: RefCounted, pub hardware_tick_cursor: AsyncQueue>>, pub testers: RefCell>>, + pub render_ctx_watchers: CopyHashMap<(ClientId, JayRenderCtxId), Rc>, } // impl Drop for State { @@ -320,6 +322,10 @@ impl State { config.graphics_initialized(); } } + + for watcher in self.render_ctx_watchers.lock().values() { + watcher.send_render_ctx(ctx); + } } fn reload_cursors(&self) { @@ -577,6 +583,7 @@ impl State { self.pending_container_render_data.clear(); self.pending_float_layout.clear(); self.pending_float_titles.clear(); + self.render_ctx_watchers.clear(); self.slow_clients.clear(); for (_, h) in self.input_device_handlers.borrow_mut().drain() { h.async_event.clear(); diff --git a/wire/jay_compositor.txt b/wire/jay_compositor.txt index f0f0144e..97e8396f 100644 --- a/wire/jay_compositor.txt +++ b/wire/jay_compositor.txt @@ -53,6 +53,10 @@ msg get_pointer = 12 { seat: id(wl_seat), } +msg get_render_ctx = 13 { + id: id(jay_render_ctx), +} + # events msg client_id = 0 { diff --git a/wire/jay_render_ctx.txt b/wire/jay_render_ctx.txt new file mode 100644 index 00000000..da36d93b --- /dev/null +++ b/wire/jay_render_ctx.txt @@ -0,0 +1,15 @@ +# requests + +msg destroy = 0 { + +} + +# events + +msg no_device = 0 { + +} + +msg device = 1 { + fd: fd, +}