Skip to content

Commit

Permalink
Add support for zwp_linux_dmabuf_v1
Browse files Browse the repository at this point in the history
Normally on the client-side this is handled by Mesa, but an
implementation is necessary for using screencopy, for instance.

This required at least version 3, which seems reasonable since that is
the same version Mesa currently requires. Applications using this will
need to handle both version 3 and version 4.
  • Loading branch information
ids1024 committed Jan 12, 2023
1 parent 327f9cd commit 6fb35a3
Show file tree
Hide file tree
Showing 4 changed files with 570 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ default = ["calloop", "xkbcommon"]
pkg-config = "0.3"

[dev-dependencies]
drm-fourcc = "2.2.0"
image = "0.23"
env_logger = "0.9"
wgpu = "0.13.1"
Expand Down
133 changes: 133 additions & 0 deletions examples/dmabuf_formats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use drm_fourcc::{DrmFourcc, DrmModifier};
use smithay_client_toolkit::{
dmabuf::{DmabufFeedback, DmabufFormat, DmabufHandler, DmabufState},
registry::{ProvidesRegistryState, RegistryState},
registry_handlers,
};
use wayland_client::{globals::registry_queue_init, protocol::wl_buffer, Connection, QueueHandle};
use wayland_protocols::wp::linux_dmabuf::zv1::client::{
zwp_linux_buffer_params_v1, zwp_linux_dmabuf_feedback_v1,
};

struct AppData {
registry_state: RegistryState,
dmabuf_state: DmabufState,
feedback: Option<DmabufFeedback>,
}

impl DmabufHandler for AppData {
fn dmabuf_state(&mut self) -> &mut DmabufState {
&mut self.dmabuf_state
}

fn dmabuf_feedback(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_proxy: &zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
feedback: DmabufFeedback,
) {
self.feedback = Some(feedback);
}

fn created(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_params: &zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
_buffer: wl_buffer::WlBuffer,
) {
}

fn failed(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_params: &zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
) {
}

fn released(
&mut self,
_conn: &Connection,
_qh: &QueueHandle<Self>,
_buffer: &wl_buffer::WlBuffer,
) {
}
}

impl ProvidesRegistryState for AppData {
fn registry(&mut self) -> &mut RegistryState {
&mut self.registry_state
}
registry_handlers![,];
}

fn main() {
env_logger::init();

let conn = Connection::connect_to_env().unwrap();

let (globals, mut event_queue) = registry_queue_init(&conn).unwrap();
let qh = event_queue.handle();

let mut app_data = AppData {
registry_state: RegistryState::new(&globals),
dmabuf_state: DmabufState::new(&globals, &qh),
feedback: None,
};

match app_data.dmabuf_state.version() {
None => println!("`zwp_linux_dmabuf_v1` version `>3` not supported by compositor."),
Some(0..=2) => unreachable!(),
Some(3) => {
println!("Version `3` of `zwp_linux_dmabuf_v1` supported. Showing modifiers.\n");

// Roundtrip after binding global to receive modifier events.
event_queue.roundtrip(&mut app_data).unwrap();

for entry in app_data.dmabuf_state.modifiers() {
print_format(entry);
}

return;
}
Some(4..) => {
println!("Version `4` of `zwp_linux_dmabuf_v1` supported. Showing default dmabuf feedback.\n");

app_data.dmabuf_state.get_default_feedback(&qh).unwrap();

let feedback = loop {
event_queue.blocking_dispatch(&mut app_data).unwrap();
if let Some(feedback) = app_data.feedback.as_ref() {
break feedback;
}
};

println!("Main device: 0x{:x}", feedback.main_device());
println!("Tranches:");
let format_table = feedback.format_table();
for tranche in feedback.tranches() {
println!(" Device: 0x{:x}", tranche.device);
println!(" Flags: {:?}", tranche.flags);
println!(" Formats");
for idx in &tranche.formats {
print!(" ");
print_format(&format_table[*idx as usize]);
}
}
}
}
}

fn print_format(format: &DmabufFormat) {
print!("Format: ");
match DrmFourcc::try_from(format.format) {
Ok(format) => print!("{:?}", format),
Err(err) => print!("{:?}", err),
}
println!(", Modifier: {:?}", DrmModifier::from(format.modifier));
}

smithay_client_toolkit::delegate_dmabuf!(AppData);
smithay_client_toolkit::delegate_registry!(AppData);
Loading

0 comments on commit 6fb35a3

Please sign in to comment.