diff --git a/src/config/app.rs b/src/config/app.rs index 39fafd9..fb9058a 100644 --- a/src/config/app.rs +++ b/src/config/app.rs @@ -1,8 +1,15 @@ use std::collections::HashMap; +#[derive(Debug, Clone, PartialEq)] +pub enum WaylandProtocol { + Any, + WlrScreencopyUnstableV1, + WlrExportDmabufUnstableV1, +} + #[derive(Debug, Clone)] pub enum Capturer { - WlrExportDmabufUnstableV1, + Wayland(WaylandProtocol), None, } diff --git a/src/config/file.rs b/src/config/file.rs index c524d6b..1b852f7 100644 --- a/src/config/file.rs +++ b/src/config/file.rs @@ -4,9 +4,11 @@ use std::collections::HashMap; #[derive(Deserialize, Debug)] pub enum Capturer { #[serde(rename = "wlroots")] - DeprecatedWlrExportDmabufUnstableV1, + Wlroots, #[serde(rename = "wlr-export-dmabuf-unstable-v1")] WlrExportDmabufUnstableV1, + #[serde(rename = "wlr-screencopy-unstable-v1")] + WlrScreencopyUnstableV1, #[serde(rename = "none")] None, } diff --git a/src/config/mod.rs b/src/config/mod.rs index 00198a2..2a64b0a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -35,12 +35,14 @@ fn parse() -> Result { min_brightness: 1, capturer: match o.capturer { file::Capturer::None => app::Capturer::None, - file::Capturer::WlrExportDmabufUnstableV1 => { - app::Capturer::WlrExportDmabufUnstableV1 + file::Capturer::Wlroots => { + app::Capturer::Wayland(app::WaylandProtocol::Any) + } + file::Capturer::WlrScreencopyUnstableV1 => { + app::Capturer::Wayland(app::WaylandProtocol::WlrScreencopyUnstableV1) } - file::Capturer::DeprecatedWlrExportDmabufUnstableV1 => { - log::warn!("capturer=\"wlroots\" is deprecated by capturer=\"wlr-export-dmabuf-unstable-v1\""); - app::Capturer::WlrExportDmabufUnstableV1 + file::Capturer::WlrExportDmabufUnstableV1 => { + app::Capturer::Wayland(app::WaylandProtocol::WlrExportDmabufUnstableV1) } }, }) @@ -51,12 +53,14 @@ fn parse() -> Result { min_brightness: 1, capturer: match o.capturer { file::Capturer::None => app::Capturer::None, - file::Capturer::WlrExportDmabufUnstableV1 => { - app::Capturer::WlrExportDmabufUnstableV1 + file::Capturer::Wlroots => { + app::Capturer::Wayland(app::WaylandProtocol::Any) + } + file::Capturer::WlrScreencopyUnstableV1 => { + app::Capturer::Wayland(app::WaylandProtocol::WlrScreencopyUnstableV1) } - file::Capturer::DeprecatedWlrExportDmabufUnstableV1 => { - log::warn!("capturer=\"wlroots\" is deprecated by capturer=\"wlr-export-dmabuf-unstable-v1\""); - app::Capturer::WlrExportDmabufUnstableV1 + file::Capturer::WlrExportDmabufUnstableV1 => { + app::Capturer::Wayland(app::WaylandProtocol::WlrExportDmabufUnstableV1) } }, }) diff --git a/src/frame/capturer/wayland.rs b/src/frame/capturer/wayland.rs index 35cd077..5226d27 100644 --- a/src/frame/capturer/wayland.rs +++ b/src/frame/capturer/wayland.rs @@ -1,8 +1,12 @@ +use crate::config::WaylandProtocol; use crate::frame::object::Object; use crate::frame::vulkan::Vulkan; use crate::predictor::Controller; +use std::os::fd::BorrowedFd; use std::thread; use std::time::Duration; +use wayland_client::protocol::wl_buffer; +use wayland_client::protocol::wl_buffer::WlBuffer; use wayland_client::protocol::wl_output; use wayland_client::protocol::wl_output::WlOutput; use wayland_client::protocol::wl_registry; @@ -10,19 +14,31 @@ use wayland_client::protocol::wl_registry::WlRegistry; use wayland_client::Connection; use wayland_client::Dispatch; use wayland_client::QueueHandle; -use wayland_protocols_wlr::export_dmabuf::v1::client::zwlr_export_dmabuf_frame_v1::Event; +use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_buffer_params_v1; +use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_buffer_params_v1::Flags; +use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1; +use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_dmabuf_v1; +use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1; +use wayland_protocols_wlr::export_dmabuf::v1::client::zwlr_export_dmabuf_frame_v1; use wayland_protocols_wlr::export_dmabuf::v1::client::zwlr_export_dmabuf_frame_v1::ZwlrExportDmabufFrameV1; use wayland_protocols_wlr::export_dmabuf::v1::client::zwlr_export_dmabuf_manager_v1; use wayland_protocols_wlr::export_dmabuf::v1::client::zwlr_export_dmabuf_manager_v1::ZwlrExportDmabufManagerV1; +use wayland_protocols_wlr::screencopy::v1::client::zwlr_screencopy_frame_v1; +use wayland_protocols_wlr::screencopy::v1::client::zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1; +use wayland_protocols_wlr::screencopy::v1::client::zwlr_screencopy_manager_v1; +use wayland_protocols_wlr::screencopy::v1::client::zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1; const DELAY_SUCCESS: Duration = Duration::from_millis(100); const DELAY_FAILURE: Duration = Duration::from_millis(1000); -#[derive(Default)] pub struct Capturer { + protocol: WaylandProtocol, + is_processing_frame: bool, vulkan: Option, output: Option, output_global_id: Option, + screencopy_manager: Option, + dmabuf: Option, dmabuf_manager: Option, pending_frame: Option, controller: Option, @@ -34,6 +50,23 @@ struct GlobalsContext { desired_output: String, } +impl Capturer { + pub fn new(protocol: WaylandProtocol) -> Self { + Self { + protocol, + is_processing_frame: false, + vulkan: None, + output: None, + output_global_id: None, + screencopy_manager: None, + dmabuf: None, + dmabuf_manager: None, + pending_frame: None, + controller: None, + } + } +} + impl super::Capturer for Capturer { fn run(&mut self, output_name: &str, controller: Controller) { let connection = @@ -59,41 +92,74 @@ impl super::Capturer for Capturer { .roundtrip(self) .expect("Unable to perform 2nd initial roundtrip"); - if self.dmabuf_manager.is_none() { - panic!("Unable to initialize ZwlrExportDmabufManagerV1 instance"); - } + let protocol_to_use = match self.protocol { + WaylandProtocol::WlrScreencopyUnstableV1 => { + if self.screencopy_manager.is_none() { + panic!("Requested to use wlr-screencopy-unstable-v1 protocol, but it's not available"); + } + log::trace!("Using wlr-screencopy-unstable-v1 protocol to request frames"); + WaylandProtocol::WlrScreencopyUnstableV1 + } + WaylandProtocol::WlrExportDmabufUnstableV1 => { + if self.dmabuf_manager.is_none() { + panic!("Requested to use wlr-export-dmabuf-unstable-v1 protocol, but it's not available"); + } + log::trace!("Using wlr-export-dmabuf-unstable-v1 protocol to request frames"); + WaylandProtocol::WlrExportDmabufUnstableV1 + } + WaylandProtocol::Any => { + if self.screencopy_manager.is_some() { + log::trace!("Using wlr-screencopy-unstable-v1 protocol to request frames"); + WaylandProtocol::WlrScreencopyUnstableV1 + } else if self.dmabuf_manager.is_some() { + log::trace!("Using wlr-export-dmabuf-unstable-v1 protocol to request frames"); + WaylandProtocol::WlrExportDmabufUnstableV1 + } else { + panic!("No supported Wayland protocols found to capture screen contents"); + } + } + }; self.vulkan = Some(Vulkan::new().expect("Unable to initialize Vulkan")); self.controller = Some(controller); loop { - if let Some(output) = self.output.as_mut() { - self.dmabuf_manager.as_mut().unwrap().capture_output( - 0, - output, - &event_queue.handle(), - (), - ); + if !self.is_processing_frame { + if let Some(output) = self.output.as_mut() { + self.is_processing_frame = true; + + match protocol_to_use { + WaylandProtocol::WlrScreencopyUnstableV1 => { + self.screencopy_manager.as_mut().unwrap().capture_output( + 0, + output, + &event_queue.handle(), + (), + ); + } + WaylandProtocol::WlrExportDmabufUnstableV1 => { + self.dmabuf_manager.as_mut().unwrap().capture_output( + 0, + output, + &event_queue.handle(), + (), + ); + } + _ => { + unreachable!(); + } + } + } } event_queue .blocking_dispatch(self) - .expect("Error running wlr-export-dmabuf-unstable-v1 capturer main loop"); + .expect("Error running wayland capturer main loop"); } } } -impl Dispatch for Capturer { - fn event( - _: &mut Self, - _: &ZwlrExportDmabufManagerV1, - _: zwlr_export_dmabuf_manager_v1::Event, - _: &(), - _: &Connection, - _: &QueueHandle, - ) { - } -} +// ==== Globals ==== impl Dispatch for Capturer { fn event( @@ -125,17 +191,90 @@ impl Dispatch for Capturer { } } +impl Dispatch for Capturer { + fn event( + state: &mut Self, + registry: &WlRegistry, + event: wl_registry::Event, + ctx: &GlobalsContext, + _: &Connection, + qh: &QueueHandle, + ) { + match event { + wl_registry::Event::Global { + name, + interface, + version, + .. + } => { + match &interface[..] { + "wl_output" => { + registry.bind::( + name, + version, + qh, + GlobalsContext { + global_id: Some(name), + desired_output: ctx.desired_output.clone(), + }, + ); + } + "zwlr_export_dmabuf_manager_v1" => { + log::trace!("Detected support for wlr-export-dmabuf-unstable-v1 protocol"); + state.dmabuf_manager = Some( + registry.bind::(name, version, qh, ()), + ); + } + "zwp_linux_dmabuf_v1" => { + state.dmabuf = + Some(registry.bind::(name, version, qh, ())); + } + "zwlr_screencopy_manager_v1" => { + log::trace!("Detected support for wlr-screencopy-unstable-v1 protocol"); + state.screencopy_manager = Some( + registry.bind::(name, version, qh, ()), + ); + } + _ => {} + }; + } + wl_registry::Event::GlobalRemove { name } => { + if Some(name) == state.output_global_id { + log::info!("Disconnected screen {}", ctx.desired_output); + state.output = None; + state.output_global_id = None; + } + } + _ => {} + } + } +} + +// ==== wlr-export-dmabuf-unstable-v1 protocol ==== + +impl Dispatch for Capturer { + fn event( + _: &mut Self, + _: &ZwlrExportDmabufManagerV1, + _: zwlr_export_dmabuf_manager_v1::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + } +} + impl Dispatch for Capturer { fn event( state: &mut Self, frame: &ZwlrExportDmabufFrameV1, - event: Event, + event: zwlr_export_dmabuf_frame_v1::Event, _: &(), _: &Connection, _: &QueueHandle, ) { match event { - Event::Frame { + zwlr_export_dmabuf_frame_v1::Event::Frame { width, height, num_objects, @@ -145,7 +284,7 @@ impl Dispatch for Capturer { state.pending_frame = Some(Object::new(width, height, num_objects, format)); } - Event::Object { + zwlr_export_dmabuf_frame_v1::Event::Object { index, fd, size, .. } => { state @@ -155,7 +294,7 @@ impl Dispatch for Capturer { .set_object(index, fd, size); } - Event::Ready { .. } => { + zwlr_export_dmabuf_frame_v1::Event::Ready { .. } => { let luma = state .vulkan .as_ref() @@ -169,14 +308,16 @@ impl Dispatch for Capturer { state.pending_frame = None; thread::sleep(DELAY_SUCCESS); + state.is_processing_frame = false; } - Event::Cancel { reason } => { + zwlr_export_dmabuf_frame_v1::Event::Cancel { reason } => { frame.destroy(); state.pending_frame = None; log::error!("Frame was cancelled, reason: {reason:?}"); thread::sleep(DELAY_FAILURE); + state.is_processing_frame = false; } _ => unreachable!(), @@ -184,49 +325,130 @@ impl Dispatch for Capturer { } } -impl Dispatch for Capturer { +// ==== wlr-screencopy-unstable-v1 protocol ==== + +impl Dispatch for Capturer { + fn event( + _: &mut Self, + _: &ZwpLinuxDmabufV1, + _: zwp_linux_dmabuf_v1::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + } +} + +impl Dispatch for Capturer { + fn event( + _: &mut Self, + _: &ZwpLinuxBufferParamsV1, + _: zwp_linux_buffer_params_v1::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + } +} + +impl Dispatch for Capturer { + fn event( + _: &mut Self, + _: &ZwlrScreencopyManagerV1, + _: zwlr_screencopy_manager_v1::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + } +} + +impl Dispatch for Capturer { + fn event( + _: &mut Self, + _: &WlBuffer, + _: wl_buffer::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + } +} + +impl Dispatch for Capturer { fn event( state: &mut Self, - registry: &WlRegistry, - event: wl_registry::Event, - ctx: &GlobalsContext, + frame: &ZwlrScreencopyFrameV1, + event: zwlr_screencopy_frame_v1::Event, + _: &(), _: &Connection, qh: &QueueHandle, ) { match event { - wl_registry::Event::Global { - name, - interface, - version, - .. + zwlr_screencopy_frame_v1::Event::LinuxDmabuf { + width, + height, + format, } => { - match &interface[..] { - "wl_output" => { - registry.bind::( - name, - version, - qh, - GlobalsContext { - global_id: Some(name), - desired_output: ctx.desired_output.clone(), - }, - ); - } - "zwlr_export_dmabuf_manager_v1" => { - state.dmabuf_manager = Some( - registry.bind::(name, version, qh, ()), - ); - } - _ => {} - }; + let pending_frame = Object::new(width, height, 1, format); + let dmabuf = state.dmabuf.as_ref().unwrap().create_params(qh, ()); + let (fd, offset, stride, modifier) = state + .vulkan + .as_ref() + .unwrap() + .init_exportable_frame_image(&pending_frame) + .expect("Unable to init exportable frame image"); + + let fd = unsafe { BorrowedFd::borrow_raw(fd) }; + + dmabuf.add( + fd, + 0, + offset as u32, + stride as u32, + (modifier >> 32) as u32, + (modifier & 0xFFFFFFFF) as u32, + ); + + let buffer = dmabuf.create_immed( + width as i32, + height as i32, + format, + Flags::empty(), + qh, + (), + ); + + frame.copy(&buffer); + state.pending_frame = Some(pending_frame); } - wl_registry::Event::GlobalRemove { name } => { - if Some(name) == state.output_global_id { - log::info!("Disconnected screen {}", ctx.desired_output); - state.output = None; - state.output_global_id = None; - } + + zwlr_screencopy_frame_v1::Event::Ready { .. } => { + let luma = state + .vulkan + .as_ref() + .unwrap() + .luma_percent(state.pending_frame.as_ref().unwrap()) + .expect("Unable to compute luma percent"); + + state.controller.as_mut().unwrap().adjust(luma); + + frame.destroy(); + state.pending_frame = None; + + thread::sleep(DELAY_SUCCESS); + state.is_processing_frame = false; + } + + zwlr_screencopy_frame_v1::Event::Failed {} => { + frame.destroy(); + state.pending_frame = None; + + log::error!("Frame copy failed"); + thread::sleep(DELAY_FAILURE); + state.is_processing_frame = false; } + _ => {} } } diff --git a/src/frame/vulkan.rs b/src/frame/vulkan.rs index d294ce2..b657091 100644 --- a/src/frame/vulkan.rs +++ b/src/frame/vulkan.rs @@ -1,5 +1,6 @@ use crate::frame::compute_perceived_lightness_percent; use crate::frame::object::Object; +use ash::khr::external_memory_fd::Device as KHRDevice; use ash::{vk, Device, Entry, Instance}; use std::cell::RefCell; use std::default::Default; @@ -18,6 +19,7 @@ pub struct Vulkan { _entry: Entry, // must keep reference to prevent early memory release instance: Instance, device: Device, + khr_device: KHRDevice, buffer: vk::Buffer, buffer_memory: vk::DeviceMemory, command_pool: vk::CommandPool, @@ -27,6 +29,8 @@ pub struct Vulkan { image: RefCell>, image_memory: RefCell>, image_resolution: RefCell>, + frame_image: RefCell>, + frame_image_memory: RefCell>, } impl Vulkan { @@ -87,6 +91,8 @@ impl Vulkan { .map_err(anyhow::Error::msg)? }; + let khr_device = KHRDevice::new(&instance, &device); + let queue = unsafe { device.get_device_queue(queue_family_index, 0) }; let pool_create_info = vk::CommandPoolCreateInfo::default() @@ -162,6 +168,7 @@ impl Vulkan { _entry: entry, instance, device, + khr_device, buffer, buffer_memory, command_pool, @@ -171,6 +178,8 @@ impl Vulkan { image: RefCell::new(None), image_memory: RefCell::new(None), image_resolution: RefCell::new(None), + frame_image: RefCell::new(None), + frame_image_memory: RefCell::new(None), }) } @@ -198,10 +207,39 @@ impl Vulkan { .borrow() .ok_or("Unable to borrow the Vulkan image")?; - let (frame_image, frame_image_memory) = self.init_frame_image(frame)?; + let (src_access_mask, src_stage_mask) = if self.frame_image.borrow().is_none() { + self.init_frame_image(frame)?; + ( + vk::AccessFlags::default(), + vk::PipelineStageFlags::TOP_OF_PIPE, + ) + } else { + (vk::AccessFlags::HOST_WRITE, vk::PipelineStageFlags::HOST) + }; + + let frame_image = self + .frame_image + .take() + .ok_or("Unable to borrow the Vulkan frame image")?; + + let frame_image_memory = self + .frame_image_memory + .take() + .ok_or("Unable to borrow the Vulkan frame image memory")?; self.begin_commands()?; + self.add_barrier( + &frame_image, + 0, + 1, + vk::ImageLayout::UNDEFINED, + vk::ImageLayout::TRANSFER_SRC_OPTIMAL, + src_access_mask, + vk::AccessFlags::TRANSFER_READ, + src_stage_mask, + ); + let (target_mip_level, mip_width, mip_height) = self.generate_mipmaps(frame, &frame_image, &image); @@ -287,10 +325,7 @@ impl Vulkan { Ok(()) } - fn init_frame_image( - &self, - frame: &Object, - ) -> Result<(vk::Image, vk::DeviceMemory), Box> { + fn init_frame_image(&self, frame: &Object) -> Result<(), Box> { // External memory info let mut frame_image_memory_info = vk::ExternalMemoryImageCreateInfo::default() .handle_types(vk::ExternalMemoryHandleTypeFlags::DMA_BUF_EXT); @@ -381,7 +416,133 @@ impl Vulkan { .map_err(anyhow::Error::msg)?; }; - Ok((frame_image, frame_image_memory)) + self.frame_image.borrow_mut().replace(frame_image); + self.frame_image_memory + .borrow_mut() + .replace(frame_image_memory); + Ok(()) + } + + pub fn init_exportable_frame_image( + &self, + frame: &Object, + ) -> Result<(i32, u64, u64, u64), Box> { + let mut frame_image_memory_info = vk::ExternalMemoryImageCreateInfo::default() + .handle_types(vk::ExternalMemoryHandleTypeFlags::DMA_BUF_EXT); + + let frame_image_create_info = vk::ImageCreateInfo::default() + .push_next(&mut frame_image_memory_info) + .image_type(vk::ImageType::TYPE_2D) + .format(vk::Format::B8G8R8A8_UNORM) + .extent(vk::Extent3D { + width: frame.width, + height: frame.height, + depth: 1, + }) + .mip_levels(1) + .array_layers(1) + .tiling(vk::ImageTiling::LINEAR) + .samples(vk::SampleCountFlags::TYPE_1) + .usage(vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + + let frame_image = unsafe { + self.device + .create_image(&frame_image_create_info, None) + .map_err(anyhow::Error::msg)? + }; + + // Memory requirements info + let frame_image_memory_req_info = + vk::ImageMemoryRequirementsInfo2::default().image(frame_image); + + // Prepare the structures to get memory requirements into, then get the memory requirements + let mut frame_image_mem_dedicated_req = vk::MemoryDedicatedRequirements::default(); + + let mut frame_image_mem_req = + vk::MemoryRequirements2::default().push_next(&mut frame_image_mem_dedicated_req); + + unsafe { + self.device.get_image_memory_requirements2( + &frame_image_memory_req_info, + &mut frame_image_mem_req, + ); + } + + // Bit i in memory_type_bits is set if the ith memory type in the + // VkPhysicalDeviceMemoryProperties structure is supported for the image memory. + // We just use the first type supported (from least significant bit's side) + + // Find suitable memory type index + let memory_type_index = frame_image_mem_req + .memory_requirements + .memory_type_bits + .trailing_zeros(); + + // Specify that the memory can be exported + let mut frame_import_memory_info = vk::ExportMemoryAllocateInfo::default() + .handle_types(vk::ExternalMemoryHandleTypeFlags::DMA_BUF_EXT); + + // dedicated allocation info + let mut frame_image_memory_dedicated_info = + vk::MemoryDedicatedAllocateInfo::default().image(frame_image); + + // Allocate memory + let mut frame_image_allocate_info = vk::MemoryAllocateInfo::default() + .push_next(&mut frame_import_memory_info) + .allocation_size(frame_image_mem_req.memory_requirements.size) + .memory_type_index(memory_type_index); + + if frame_image_mem_dedicated_req.prefers_dedicated_allocation == vk::TRUE { + frame_image_allocate_info = + frame_image_allocate_info.push_next(&mut frame_image_memory_dedicated_info); + } + + // Allocate memory and bind it to the image + let frame_image_memory = unsafe { + self.device + .allocate_memory(&frame_image_allocate_info, None) + .map_err(anyhow::Error::msg)? + }; + + // Bind memory to the image + unsafe { + self.device + .bind_image_memory(frame_image, frame_image_memory, 0) + .map_err(anyhow::Error::msg)?; + } + + // Get the file descriptor + let memory_fd_info = vk::MemoryGetFdInfoKHR::default() + .memory(frame_image_memory) + .handle_type(vk::ExternalMemoryHandleTypeFlags::DMA_BUF_EXT); + + let fd = unsafe { + self.khr_device + .get_memory_fd(&memory_fd_info) + .map_err(anyhow::Error::msg)? + }; + + self.frame_image.borrow_mut().replace(frame_image); + self.frame_image_memory + .borrow_mut() + .replace(frame_image_memory); + + let subresource = vk::ImageSubresource::default() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .mip_level(0) + .array_layer(0); + + let layout = unsafe { + self.device + .get_image_subresource_layout(frame_image, subresource) + }; + + let offset = layout.offset; + let stride = layout.row_pitch; + let modifier: u64 = 0; // DRM_FORMAT_MOD_LINEAR + + Ok((fd, offset, stride, modifier)) } #[allow(clippy::too_many_arguments)] @@ -486,17 +647,6 @@ impl Vulkan { ) -> (u32, u32, u32) { let (mut mip_width, mut mip_height, mip_levels) = image_dimensions(frame); - self.add_barrier( - frame_image, - 0, - 1, - vk::ImageLayout::UNDEFINED, - vk::ImageLayout::TRANSFER_SRC_OPTIMAL, - vk::AccessFlags::default(), - vk::AccessFlags::TRANSFER_READ, - vk::PipelineStageFlags::TOP_OF_PIPE, - ); - self.add_barrier( image, 0, diff --git a/src/main.rs b/src/main.rs index 196dd7b..9035ed5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,10 +69,9 @@ fn main() { .spawn(move || { let mut frame_capturer: Box = match output_capturer { - config::Capturer::WlrExportDmabufUnstableV1 => Box::< - frame::capturer::wlr_export_dmabuf_unstable_v1::Capturer, - >::default( - ), + config::Capturer::Wayland(protocol) => { + Box::new(frame::capturer::wayland::Capturer::new(protocol)) + } config::Capturer::None => { Box::::default() }