1
0
Fork 0
forked from wry/wry

config: allow disabling direct scanout

This commit is contained in:
Julian Orth 2024-02-18 20:44:56 +01:00
parent da84e9ec27
commit 114c293950
9 changed files with 63 additions and 1 deletions

View file

@ -511,6 +511,10 @@ impl Client {
self.send(&ClientMessage::SetGfxApi { device, api });
}
pub fn set_direct_scanout_enabled(&self, device: Option<DrmDevice>, enabled: bool) {
self.send(&ClientMessage::SetDirectScanoutEnabled { device, enabled });
}
pub fn connector_connected(&self, connector: Connector) -> bool {
let res = self.send_with_response(&ClientMessage::ConnectorConnected { connector });
get_response!(res, false, ConnectorConnected { connected });

View file

@ -338,6 +338,10 @@ pub enum ClientMessage<'a> {
device: Option<DrmDevice>,
api: GfxApi,
},
SetDirectScanoutEnabled {
device: Option<DrmDevice>,
enabled: bool,
},
}
#[derive(Serialize, Deserialize, Debug)]

View file

@ -369,6 +369,11 @@ impl DrmDevice {
pub fn set_gfx_api(self, gfx_api: GfxApi) {
get!().set_gfx_api(Some(self), gfx_api);
}
/// Enables or disables direct scanout of client surfaces for this device.
pub fn set_direct_scanout_enabled(self, enabled: bool) {
get!().set_direct_scanout_enabled(Some(self), enabled);
}
}
/// A graphics API.
@ -389,3 +394,12 @@ pub enum GfxApi {
pub fn set_gfx_api(gfx_api: GfxApi) {
get!().set_gfx_api(None, gfx_api);
}
/// Enables or disables direct scanout of client surfaces.
///
/// The default is `true`.
///
/// This setting can be overwritten per-device with [DrmDevice::set_direct_scanout_enabled].
pub fn set_direct_scanout_enabled(enabled: bool) {
get!().set_direct_scanout_enabled(None, enabled);
}

View file

@ -230,4 +230,5 @@ pub trait BackendDrmDevice {
fn set_gfx_api(&self, api: GfxApi);
fn gtx_api(&self) -> GfxApi;
fn version(&self) -> Result<DrmVersion, DrmError>;
fn set_direct_scanout_enabled(&self, enabled: bool);
}

View file

@ -81,6 +81,7 @@ pub struct MetalDrmDevice {
pub handle_events: HandleEvents,
pub ctx: CloneCell<Rc<MetalRenderContext>>,
pub on_change: OnChange<crate::backend::DrmEvent>,
pub direct_scanout_enabled: Cell<Option<bool>>,
}
impl BackendDrmDevice for MetalDrmDevice {
@ -115,6 +116,10 @@ impl BackendDrmDevice for MetalDrmDevice {
fn version(&self) -> Result<DrmVersion, DrmError> {
self.gbm.drm.version()
}
fn set_direct_scanout_enabled(&self, enabled: bool) {
self.direct_scanout_enabled.set(Some(enabled));
}
}
pub struct HandleEvents {
@ -466,6 +471,13 @@ impl MetalConnector {
data
}
fn direct_scanout_enabled(&self) -> bool {
self.dev
.direct_scanout_enabled
.get()
.unwrap_or(self.state.direct_scanout_enabled.get())
}
fn prepare_present_fb(
&self,
rr: &mut RenderResult,
@ -485,7 +497,9 @@ impl MetalConnector {
output.global.preferred_scale.get(),
render_hw_cursor,
);
let try_direct_scanout = try_direct_scanout && !output.global.have_shm_screencopies();
let try_direct_scanout = try_direct_scanout
&& !output.global.have_shm_screencopies()
&& self.direct_scanout_enabled();
let mut direct_scanout_data = None;
if try_direct_scanout {
if let Some(dsd) = self.prepare_direct_scanout(&pass, plane) {
@ -1394,6 +1408,7 @@ impl MetalBackend {
},
ctx: CloneCell::new(ctx),
on_change: Default::default(),
direct_scanout_enabled: Default::default(),
});
let (connectors, futures) = get_connectors(self, &dev, &resources.connectors)?;

View file

@ -989,6 +989,10 @@ impl BackendDrmDevice for XDrmDevice {
fn version(&self) -> Result<DrmVersion, DrmError> {
self.backend.gbm.drm.version()
}
fn set_direct_scanout_enabled(&self, enabled: bool) {
let _ = enabled;
}
}
struct XOutput {

View file

@ -203,6 +203,7 @@ fn start_compositor2(
toplevel_lists: Default::default(),
dma_buf_ids: Default::default(),
drm_feedback_ids: Default::default(),
direct_scanout_enabled: Cell::new(true),
});
state.tracker.register(ClientId::from_raw(0));
create_dummy_output(&state);

View file

@ -590,6 +590,21 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_set_direct_scanout_enabled(
&self,
device: Option<DrmDevice>,
enabled: bool,
) -> Result<(), CphError> {
match device {
Some(dev) => self
.get_drm_device(dev)?
.dev
.set_direct_scanout_enabled(enabled),
_ => self.state.direct_scanout_enabled.set(enabled),
}
Ok(())
}
fn handle_get_default_workspace_capture(&self) {
self.respond(Response::GetDefaultWorkspaceCapture {
capture: self.state.default_workspace_capture.get(),
@ -1320,6 +1335,9 @@ impl ConfigProxyHandler {
ClientMessage::SetGfxApi { device, api } => {
self.handle_set_gfx_api(device, api).wrn("set_gfx_api")?
}
ClientMessage::SetDirectScanoutEnabled { device, enabled } => self
.handle_set_direct_scanout_enabled(device, enabled)
.wrn("set_direct_scanout_enabled")?,
}
Ok(())
}

View file

@ -144,6 +144,7 @@ pub struct State {
CopyHashMap<(ClientId, ExtForeignToplevelListV1Id), Rc<ExtForeignToplevelListV1>>,
pub dma_buf_ids: DmaBufIds,
pub drm_feedback_ids: DrmFeedbackIds,
pub direct_scanout_enabled: Cell<bool>,
}
// impl Drop for State {