diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-03 11:38:36 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-03 18:05:15 +0400 |
| commit | de3fc2def0cf3683fff7994cd294d325e4f033b2 (patch) | |
| tree | 2190d42fd228547f36f454120ec5c6a767076dfb | |
| parent | fd1d4b07fd46e298131d9030ea49dc3453e5e478 (diff) | |
| download | niri-de3fc2def0cf3683fff7994cd294d325e4f033b2.tar.gz niri-de3fc2def0cf3683fff7994cd294d325e4f033b2.tar.bz2 niri-de3fc2def0cf3683fff7994cd294d325e4f033b2.zip | |
Make rendering generic over renderer
| -rw-r--r-- | src/backend/tty.rs | 2 | ||||
| -rw-r--r-- | src/backend/winit.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/niri.rs | 234 | ||||
| -rw-r--r-- | src/render_helpers.rs | 126 | ||||
| -rw-r--r-- | src/screenshot_ui.rs | 134 |
6 files changed, 448 insertions, 51 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 67aa6af0..34798008 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -898,7 +898,7 @@ impl Tty { let renderer = &mut device.gles; // Render the elements. - let elements = niri.render(renderer, output, true); + let elements = niri.render::<GlesRenderer>(renderer, output, true); // Hand them over to the DRM. let drm_compositor = &mut surface.compositor; diff --git a/src/backend/winit.rs b/src/backend/winit.rs index b3c89e17..492215b5 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -140,7 +140,7 @@ impl Winit { let _span = tracy_client::span!("Winit::render"); // Render the elements. - let elements = niri.render(self.backend.renderer(), output, true); + let elements = niri.render::<GlesRenderer>(self.backend.renderer(), output, true); // Hand them over to winit. self.backend.bind().unwrap(); diff --git a/src/main.rs b/src/main.rs index b19a5426..667f1d6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod handlers; mod input; mod layout; mod niri; +mod render_helpers; mod screenshot_ui; mod utils; mod watcher; diff --git a/src/niri.rs b/src/niri.rs index c07bb081..d251ef6b 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -17,12 +17,15 @@ use smithay::backend::renderer::element::surface::{ }; use smithay::backend::renderer::element::texture::TextureRenderElement; use smithay::backend::renderer::element::{ - default_primary_scanout_output_compare, render_elements, AsRenderElements, Kind, RenderElement, - RenderElementStates, + default_primary_scanout_output_compare, AsRenderElements, Element, Id, Kind, RenderElement, + RenderElementStates, UnderlyingStorage, +}; +use smithay::backend::renderer::gles::{ + GlesError, GlesFrame, GlesMapping, GlesRenderer, GlesTexture, }; -use smithay::backend::renderer::gles::{GlesMapping, GlesRenderer, GlesTexture}; use smithay::backend::renderer::sync::SyncPoint; -use smithay::backend::renderer::{Bind, ExportMem, Frame, ImportAll, Offscreen, Renderer}; +use smithay::backend::renderer::utils::CommitCounter; +use smithay::backend::renderer::{Bind, ExportMem, Frame, Offscreen, Renderer}; use smithay::desktop::utils::{ bbox_from_surface_tree, output_update, send_dmabuf_feedback_surface_tree, send_frames_surface_tree, surface_presentation_feedback_flags_from_states, @@ -50,7 +53,7 @@ use smithay::reexports::wayland_server::backend::{ use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::{Display, DisplayHandle}; use smithay::utils::{ - ClockSource, Logical, Monotonic, Physical, Point, Rectangle, Scale, Size, Transform, + Buffer, ClockSource, Logical, Monotonic, Physical, Point, Rectangle, Scale, Size, Transform, SERIAL_COUNTER, }; use smithay::wayland::compositor::{ @@ -92,6 +95,7 @@ use crate::handlers::configure_lock_surface; use crate::input::TabletData; use crate::layout::{Layout, MonitorRenderElement}; use crate::pw_utils::{Cast, PipeWire}; +use crate::render_helpers::{NiriRenderer, PrimaryGpuTextureRenderElement}; use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement}; use crate::utils::{ center, get_monotonic_time, make_screenshot_path, output_size, write_png_rgba8, @@ -1303,11 +1307,11 @@ impl Niri { }; } - pub fn pointer_element( + pub fn pointer_element<R: NiriRenderer>( &self, - renderer: &mut GlesRenderer, + renderer: &mut R, output: &Output, - ) -> Vec<OutputRenderElements<GlesRenderer>> { + ) -> Vec<OutputRenderElements<R>> { let _span = tracy_client::span!("Niri::pointer_element"); let output_scale = output.current_scale(); let output_pos = self.global_space.output_geometry(output).unwrap().loc; @@ -1351,19 +1355,23 @@ impl Niri { let pointer_pos = (pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale); - let texture = self - .cursor_texture_cache - .get(renderer, icon, scale, &cursor, idx); + let texture = self.cursor_texture_cache.get( + renderer.as_gles_renderer(), + icon, + scale, + &cursor, + idx, + ); let pointer_elements = vec![OutputRenderElements::NamedPointer( - TextureRenderElement::from_texture_buffer( + PrimaryGpuTextureRenderElement(TextureRenderElement::from_texture_buffer( pointer_pos.to_f64(), &texture, None, None, None, Kind::Cursor, - ), + )), )]; (pointer_elements, pointer_pos) @@ -1496,12 +1504,12 @@ impl Niri { } } - pub fn render( + pub fn render<R: NiriRenderer>( &self, - renderer: &mut GlesRenderer, + renderer: &mut R, output: &Output, include_pointer: bool, - ) -> Vec<OutputRenderElements<GlesRenderer>> { + ) -> Vec<OutputRenderElements<R>> { let _span = tracy_client::span!("Niri::render"); let output_scale = Scale::from(output.current_scale().fractional_scale()); @@ -1573,8 +1581,7 @@ impl Niri { // Get layer-shell elements. let layer_map = layer_map_for_output(output); - let mut extend_from_layer = |elements: &mut Vec<OutputRenderElements<GlesRenderer>>, - layer| { + let mut extend_from_layer = |elements: &mut Vec<OutputRenderElements<R>>, layer| { let iter = layer_map .layers_on(layer) .filter_map(|surface| { @@ -2059,7 +2066,8 @@ impl Niri { let dmabuf = cast.dmabufs.borrow()[&fd].clone(); // FIXME: Hidden / embedded / metadata cursor - let elements = elements.get_or_insert_with(|| self.render(renderer, output, true)); + let elements = elements + .get_or_insert_with(|| self.render::<GlesRenderer>(renderer, output, true)); if let Err(err) = render_to_dmabuf(renderer, dmabuf, size, scale, elements) { error!("error rendering to dmabuf: {err:?}"); @@ -2126,7 +2134,7 @@ impl Niri { .filter_map(|output| { let size = output.current_mode().unwrap().size; let scale = Scale::from(output.current_scale().fractional_scale()); - let elements = self.render(renderer, &output, true); + let elements = self.render::<GlesRenderer>(renderer, &output, true); let res = render_to_texture(renderer, size, scale, Fourcc::Abgr8888, &elements); let screenshot = match res { @@ -2153,7 +2161,7 @@ impl Niri { let size = output.current_mode().unwrap().size; let scale = Scale::from(output.current_scale().fractional_scale()); - let elements = self.render(renderer, output, true); + let elements = self.render::<GlesRenderer>(renderer, output, true); let pixels = render_to_vec(renderer, size, scale, Fourcc::Abgr8888, &elements)?; self.save_screenshot(size, pixels) @@ -2277,7 +2285,7 @@ impl Niri { size.w = max(size.w, geom.loc.x + geom.size.w); size.h = max(size.h, geom.loc.y + geom.size.h); - let output_elements = self.render(renderer, &output, include_pointer); + let output_elements = self.render::<GlesRenderer>(renderer, &output, include_pointer); elements.extend(output_elements.into_iter().map(|elem| { RelocateRenderElement::from_element(elem, geom.loc, Relocate::Relative) })); @@ -2382,16 +2390,6 @@ impl Niri { } } -render_elements! { - #[derive(Debug)] - pub OutputRenderElements<R> where R: ImportAll; - Monitor = MonitorRenderElement<R>, - Wayland = WaylandSurfaceRenderElement<R>, - NamedPointer = TextureRenderElement<<R as Renderer>::TextureId>, - SolidColor = SolidColorRenderElement, - ScreenshotUi = ScreenshotUiRenderElement<R>, -} - #[derive(Default)] pub struct ClientState { pub compositor_state: CompositorClientState, @@ -2482,8 +2480,6 @@ fn render_to_dmabuf( scale: Scale<f64>, elements: &[OutputRenderElements<GlesRenderer>], ) -> anyhow::Result<()> { - use smithay::backend::renderer::element::Element; - let _span = tracy_client::span!("render_to_dmabuf"); let output_rect = Rectangle::from_loc_and_size((0, 0), size); @@ -2505,3 +2501,173 @@ fn render_to_dmabuf( Ok(()) } + +// Manual RenderElement implementation due to AsGlesFrame requirement. +#[derive(Debug)] +pub enum OutputRenderElements<R: NiriRenderer> { + Monitor(MonitorRenderElement<R>), + Wayland(WaylandSurfaceRenderElement<R>), + NamedPointer(PrimaryGpuTextureRenderElement), + SolidColor(SolidColorRenderElement), + ScreenshotUi(ScreenshotUiRenderElement), +} + +impl<R: NiriRenderer> Element for OutputRenderElements<R> { + fn id(&self) -> &Id { + match self { + Self::Monitor(elem) => elem.id(), + Self::Wayland(elem) => elem.id(), + Self::NamedPointer(elem) => elem.id(), + Self::SolidColor(elem) => elem.id(), + Self::ScreenshotUi(elem) => elem.id(), + } + } + + fn current_commit(&self) -> CommitCounter { + match self { + Self::Monitor(elem) => elem.current_commit(), + Self::Wayland(elem) => elem.current_commit(), + Self::NamedPointer(elem) => elem.current_commit(), + Self::SolidColor(elem) => elem.current_commit(), + Self::ScreenshotUi(elem) => elem.current_commit(), + } + } + + fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> { + match self { + Self::Monitor(elem) => elem.geometry(scale), + Self::Wayland(elem) => elem.geometry(scale), + Self::NamedPointer(elem) => elem.geometry(scale), + Self::SolidColor(elem) => elem.geometry(scale), + Self::ScreenshotUi(elem) => elem.geometry(scale), + } + } + + fn transform(&self) -> Transform { + match self { + Self::Monitor(elem) => elem.transform(), + Self::Wayland(elem) => elem.transform(), + Self::NamedPointer(elem) => elem.transform(), + Self::SolidColor(elem) => elem.transform(), + Self::ScreenshotUi(elem) => elem.transform(), + } + } + + fn src(&self) -> Rectangle<f64, Buffer> { + match self { + Self::Monitor(elem) => elem.src(), + Self::Wayland(elem) => elem.src(), + Self::NamedPointer(elem) => elem.src(), + Self::SolidColor(elem) => elem.src(), + Self::ScreenshotUi(elem) => elem.src(), + } + } + + fn damage_since( + &self, + scale: Scale<f64>, + commit: Option<CommitCounter>, + ) -> Vec<Rectangle<i32, Physical>> { + match self { + Self::Monitor(elem) => elem.damage_since(scale, commit), + Self::Wayland(elem) => elem.damage_since(scale, commit), + Self::NamedPointer(elem) => elem.damage_since(scale, commit), + Self::SolidColor(elem) => elem.damage_since(scale, commit), + Self::ScreenshotUi(elem) => elem.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, Physical>> { + match self { + Self::Monitor(elem) => elem.opaque_regions(scale), + Self::Wayland(elem) => elem.opaque_regions(scale), + Self::NamedPointer(elem) => elem.opaque_regions(scale), + Self::SolidColor(elem) => elem.opaque_regions(scale), + Self::ScreenshotUi(elem) => elem.opaque_regions(scale), + } + } + + fn alpha(&self) -> f32 { + match self { + Self::Monitor(elem) => elem.alpha(), + Self::Wayland(elem) => elem.alpha(), + Self::NamedPointer(elem) => elem.alpha(), + Self::SolidColor(elem) => elem.alpha(), + Self::ScreenshotUi(elem) => elem.alpha(), + } + } + + fn kind(&self) -> Kind { + match self { + Self::Monitor(elem) => elem.kind(), + Self::Wayland(elem) => elem.kind(), + Self::NamedPointer(elem) => elem.kind(), + Self::SolidColor(elem) => elem.kind(), + Self::ScreenshotUi(elem) => elem.kind(), + } + } +} + +impl RenderElement<GlesRenderer> for OutputRenderElements<GlesRenderer> { + fn draw( + &self, + frame: &mut GlesFrame<'_>, + src: Rectangle<f64, Buffer>, + dst: Rectangle<i32, Physical>, + damage: &[Rectangle<i32, Physical>], + ) -> Result<(), GlesError> { + match self { + Self::Monitor(elem) => elem.draw(frame, src, dst, damage), + Self::Wayland(elem) => elem.draw(frame, src, dst, damage), + Self::NamedPointer(elem) => { + RenderElement::<GlesRenderer>::draw(&elem, frame, src, dst, damage) + } + Self::SolidColor(elem) => { + RenderElement::<GlesRenderer>::draw(&elem, frame, src, dst, damage) + } + Self::ScreenshotUi(elem) => { + RenderElement::<GlesRenderer>::draw(&elem, frame, src, dst, damage) + } + } + } + + fn underlying_storage(&self, renderer: &mut GlesRenderer) -> Option<UnderlyingStorage> { + match self { + Self::Monitor(elem) => elem.underlying_storage(renderer), + Self::Wayland(elem) => elem.underlying_storage(renderer), + Self::NamedPointer(elem) => elem.underlying_storage(renderer), + Self::SolidColor(elem) => elem.underlying_storage(renderer), + Self::ScreenshotUi(elem) => elem.underlying_storage(renderer), + } + } +} + +impl<R: NiriRenderer> From<MonitorRenderElement<R>> for OutputRenderElements<R> { + fn from(x: MonitorRenderElement<R>) -> Self { + Self::Monitor(x) + } +} + +impl<R: NiriRenderer> From<WaylandSurfaceRenderElement<R>> for OutputRenderElements<R> { + fn from(x: WaylandSurfaceRenderElement<R>) -> Self { + Self::Wayland(x) + } +} + +impl<R: NiriRenderer> From<PrimaryGpuTextureRenderElement> for OutputRenderElements<R> { + fn from(x: PrimaryGpuTextureRenderElement) -> Self { + Self::NamedPointer(x) + } +} + +impl<R: NiriRenderer> From<SolidColorRenderElement> for OutputRenderElements<R> { + fn from(x: SolidColorRenderElement) -> Self { + Self::SolidColor(x) + } +} + +impl<R: NiriRenderer> From<ScreenshotUiRenderElement> for OutputRenderElements<R> { + fn from(x: ScreenshotUiRenderElement) -> Self { + Self::ScreenshotUi(x) + } +} diff --git a/src/render_helpers.rs b/src/render_helpers.rs new file mode 100644 index 00000000..922ff59c --- /dev/null +++ b/src/render_helpers.rs @@ -0,0 +1,126 @@ +use smithay::backend::allocator::dmabuf::Dmabuf; +use smithay::backend::renderer::element::texture::TextureRenderElement; +use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage}; +use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, GlesTexture}; +use smithay::backend::renderer::utils::CommitCounter; +use smithay::backend::renderer::{Bind, ExportMem, ImportAll, Offscreen, Renderer, Texture}; +use smithay::utils::{Buffer, Physical, Rectangle, Scale, Transform}; + +/// Trait with our main renderer requirements to save on the typing. +pub trait NiriRenderer: + ImportAll + + ExportMem + + Bind<Dmabuf> + + Offscreen<GlesTexture> + + Renderer<TextureId = Self::NiriTextureId, Error = Self::NiriError> + + AsGlesRenderer +{ + // Associated types to work around the instability of associated type bounds. + type NiriTextureId: Texture + Clone + 'static; + type NiriError: std::error::Error + + Send + + Sync + + From<<GlesRenderer as Renderer>::Error> + + 'static; +} + +impl<R> NiriRenderer for R +where + R: ImportAll + ExportMem + Bind<Dmabuf> + Offscreen<GlesTexture> + AsGlesRenderer, + R::TextureId: Texture + Clone + 'static, + R::Error: std::error::Error + Send + Sync + From<<GlesRenderer as Renderer>::Error> + 'static, +{ + type NiriTextureId = R::TextureId; + type NiriError = R::Error; +} + +/// Trait for getting the underlying `GlesRenderer`. +pub trait AsGlesRenderer { + fn as_gles_renderer(&mut self) -> &mut GlesRenderer; +} + +impl AsGlesRenderer for GlesRenderer { + fn as_gles_renderer(&mut self) -> &mut GlesRenderer { + self + } +} + +/// Trait for getting the underlying `GlesFrame`. +pub trait AsGlesFrame<'frame> +where + Self: 'frame, +{ + fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame>; +} + +impl<'frame> AsGlesFrame<'frame> for GlesFrame<'frame> { + fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame> { + self + } +} + +/// Wrapper for a texture from the primary GPU for rendering with the primary GPU. +#[derive(Debug)] +pub struct PrimaryGpuTextureRenderElement(pub TextureRenderElement<GlesTexture>); + +impl Element for PrimaryGpuTextureRenderElement { + fn id(&self) -> &Id { + self.0.id() + } + + fn current_commit(&self) -> CommitCounter { + self.0.current_commit() + } + + fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> { + self.0.geometry(scale) + } + + fn transform(&self) -> Transform { + self.0.transform() + } + + fn src(&self) -> Rectangle<f64, Buffer> { + self.0.src() + } + + fn damage_since( + &self, + scale: Scale<f64>, + commit: Option<CommitCounter>, + ) -> Vec<Rectangle<i32, Physical>> { + self.0.damage_since(scale, commit) + } + + fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, Physical>> { + self.0.opaque_regions(scale) + } + + fn alpha(&self) -> f32 { + self.0.alpha() + } + + fn kind(&self) -> Kind { + self.0.kind() + } +} + +impl RenderElement<GlesRenderer> for PrimaryGpuTextureRenderElement { + fn draw( + &self, + frame: &mut GlesFrame<'_>, + src: Rectangle<f64, Buffer>, + dst: Rectangle<i32, Physical>, + damage: &[Rectangle<i32, Physical>], + ) -> Result<(), GlesError> { + let gles_frame = frame.as_gles_frame(); + RenderElement::<GlesRenderer>::draw(&self.0, gles_frame, src, dst, damage)?; + Ok(()) + } + + fn underlying_storage(&self, _renderer: &mut GlesRenderer) -> Option<UnderlyingStorage> { + // If scanout for things other than Wayland buffers is implemented, this will need to take + // the target GPU into account. + None + } +} diff --git a/src/screenshot_ui.rs b/src/screenshot_ui.rs index 446442cd..eddda0b0 100644 --- a/src/screenshot_ui.rs +++ b/src/screenshot_ui.rs @@ -9,15 +9,16 @@ use smithay::backend::allocator::Fourcc; use smithay::backend::input::{ButtonState, MouseButton}; use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement}; use smithay::backend::renderer::element::texture::{TextureBuffer, TextureRenderElement}; -use smithay::backend::renderer::element::Kind; -use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture}; +use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage}; +use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, GlesTexture}; +use smithay::backend::renderer::utils::CommitCounter; use smithay::backend::renderer::ExportMem; use smithay::input::keyboard::{Keysym, ModifiersState}; use smithay::output::{Output, WeakOutput}; -use smithay::render_elements; -use smithay::utils::{Physical, Point, Rectangle, Size, Transform}; +use smithay::utils::{Buffer, Physical, Point, Rectangle, Scale, Size, Transform}; use crate::config::Action; +use crate::render_helpers::PrimaryGpuTextureRenderElement; const BORDER: i32 = 2; @@ -45,11 +46,10 @@ pub struct OutputData { locations: [Point<i32, Physical>; 8], } -render_elements! { - #[derive(Debug)] - pub ScreenshotUiRenderElement<R>; - Screenshot = TextureRenderElement<R::TextureId>, - SolidColor = SolidColorRenderElement, +#[derive(Debug)] +pub enum ScreenshotUiRenderElement { + Screenshot(PrimaryGpuTextureRenderElement), + SolidColor(SolidColorRenderElement), } impl ScreenshotUi { @@ -236,10 +236,7 @@ impl ScreenshotUi { } } - pub fn render_output( - &self, - output: &Output, - ) -> ArrayVec<ScreenshotUiRenderElement<GlesRenderer>, 9> { + pub fn render_output(&self, output: &Output) -> ArrayVec<ScreenshotUiRenderElement, 9> { let _span = tracy_client::span!("ScreenshotUi::render_output"); let Self::Open { output_data, .. } = self else { @@ -266,14 +263,14 @@ impl ScreenshotUi { // The screenshot itself goes last. elements.push( - TextureRenderElement::from_texture_buffer( + PrimaryGpuTextureRenderElement(TextureRenderElement::from_texture_buffer( (0., 0.), &output_data.texture_buffer, None, None, None, Kind::Unspecified, - ) + )) .into(), ); @@ -446,3 +443,110 @@ pub fn rect_from_corner_points( let y2 = max(a.y, b.y); Rectangle::from_extemities((x1, y1), (x2 + scale, y2 + scale)) } + +// Manual RenderElement implementation due to AsGlesFrame requirement. +impl Element for ScreenshotUiRenderElement { + fn id(&self) -> &Id { + match self { + Self::Screenshot(elem) => elem.id(), + Self::SolidColor(elem) => elem.id(), + } + } + + fn current_commit(&self) -> CommitCounter { + match self { + Self::Screenshot(elem) => elem.current_commit(), + Self::SolidColor(elem) => elem.current_commit(), + } + } + + fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> { + match self { + Self::Screenshot(elem) => elem.geometry(scale), + Self::SolidColor(elem) => elem.geometry(scale), + } + } + + fn transform(&self) -> Transform { + match self { + Self::Screenshot(elem) => elem.transform(), + Self::SolidColor(elem) => elem.transform(), + } + } + + fn src(&self) -> Rectangle<f64, Buffer> { + match self { + Self::Screenshot(elem) => elem.src(), + Self::SolidColor(elem) => elem.src(), + } + } + + fn damage_since( + &self, + scale: Scale<f64>, + commit: Option<CommitCounter>, + ) -> Vec<Rectangle<i32, Physical>> { + match self { + Self::Screenshot(elem) => elem.damage_since(scale, commit), + Self::SolidColor(elem) => elem.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, Physical>> { + match self { + Self::Screenshot(elem) => elem.opaque_regions(scale), + Self::SolidColor(elem) => elem.opaque_regions(scale), + } + } + + fn alpha(&self) -> f32 { + match self { + Self::Screenshot(elem) => elem.alpha(), + Self::SolidColor(elem) => elem.alpha(), + } + } + + fn kind(&self) -> Kind { + match self { + Self::Screenshot(elem) => elem.kind(), + Self::SolidColor(elem) => elem.kind(), + } + } +} + +impl RenderElement<GlesRenderer> for ScreenshotUiRenderElement { + fn draw( + &self, + frame: &mut GlesFrame<'_>, + src: Rectangle<f64, Buffer>, + dst: Rectangle<i32, Physical>, + damage: &[Rectangle<i32, Physical>], + ) -> Result<(), GlesError> { + match self { + Self::Screenshot(elem) => { + RenderElement::<GlesRenderer>::draw(&elem, frame, src, dst, damage) + } + Self::SolidColor(elem) => { + RenderElement::<GlesRenderer>::draw(&elem, frame, src, dst, damage) + } + } + } + + fn underlying_storage(&self, _renderer: &mut GlesRenderer) -> Option<UnderlyingStorage> { + // If scanout for things other than Wayland buffers is implemented, this will need to take + // the target GPU into account. + None + } +} + +impl From<SolidColorRenderElement> for ScreenshotUiRenderElement { + fn from(x: SolidColorRenderElement) -> Self { + Self::SolidColor(x) + } +} + +impl From<PrimaryGpuTextureRenderElement> for ScreenshotUiRenderElement { + fn from(x: PrimaryGpuTextureRenderElement) -> Self { + Self::Screenshot(x) + } +} |
