mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Split render_helpers.rs
This commit is contained in:
@@ -3,7 +3,7 @@ use std::cmp::{max, min};
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use niri::layout::{LayoutElement, LayoutElementRenderElement};
|
use niri::layout::{LayoutElement, LayoutElementRenderElement};
|
||||||
use niri::render_helpers::NiriRenderer;
|
use niri::render_helpers::renderer::NiriRenderer;
|
||||||
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
|
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
|
||||||
use smithay::backend::renderer::element::Kind;
|
use smithay::backend::renderer::element::Kind;
|
||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ use wayland_protocols::wp::presentation_time::server::wp_presentation_feedback;
|
|||||||
use super::RenderResult;
|
use super::RenderResult;
|
||||||
use crate::frame_clock::FrameClock;
|
use crate::frame_clock::FrameClock;
|
||||||
use crate::niri::{Niri, RedrawState, State};
|
use crate::niri::{Niri, RedrawState, State};
|
||||||
use crate::render_helpers::AsGlesRenderer;
|
use crate::render_helpers::renderer::AsGlesRenderer;
|
||||||
use crate::utils::get_monotonic_time;
|
use crate::utils::get_monotonic_time;
|
||||||
|
|
||||||
const SUPPORTED_COLOR_FORMATS: &[Fourcc] = &[Fourcc::Argb8888, Fourcc::Abgr8888];
|
const SUPPORTED_COLOR_FORMATS: &[Fourcc] = &[Fourcc::Argb8888, Fourcc::Abgr8888];
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use smithay::reexports::gbm::Format as Fourcc;
|
|||||||
use smithay::utils::Transform;
|
use smithay::utils::Transform;
|
||||||
|
|
||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
|
|
||||||
const TEXT: &str = "Failed to parse the config file. \
|
const TEXT: &str = "Failed to parse the config file. \
|
||||||
Please run <span face='monospace' bgcolor='#000000'>niri validate</span> \
|
Please run <span face='monospace' bgcolor='#000000'>niri validate</span> \
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use smithay::output::Output;
|
|||||||
use smithay::reexports::gbm::Format as Fourcc;
|
use smithay::reexports::gbm::Format as Fourcc;
|
||||||
use smithay::utils::Transform;
|
use smithay::utils::Transform;
|
||||||
|
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
|
|
||||||
const TEXT: &str = "Are you sure you want to exit niri?\n\n\
|
const TEXT: &str = "Are you sure you want to exit niri?\n\n\
|
||||||
Press <span face='mono' bgcolor='#2C2C2C'> Enter </span> to confirm.";
|
Press <span face='mono' bgcolor='#2C2C2C'> Enter </span> to confirm.";
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use smithay::reexports::gbm::Format as Fourcc;
|
|||||||
use smithay::utils::{Physical, Size, Transform};
|
use smithay::utils::{Physical, Size, Transform};
|
||||||
|
|
||||||
use crate::input::CompositorMod;
|
use crate::input::CompositorMod;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
|
|
||||||
const PADDING: i32 = 8;
|
const PADDING: i32 = 8;
|
||||||
const MARGIN: i32 = PADDING * 2;
|
const MARGIN: i32 = PADDING * 2;
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ use self::monitor::{Monitor, WorkspaceSwitch, WorkspaceSwitchGesture};
|
|||||||
use self::workspace::{compute_working_area, Column, ColumnWidth, OutputId, Workspace};
|
use self::workspace::{compute_working_area, Column, ColumnWidth, OutputId, Workspace};
|
||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
|
|
||||||
pub mod focus_ring;
|
pub mod focus_ring;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use super::workspace::{
|
|||||||
};
|
};
|
||||||
use super::{LayoutElement, Options};
|
use super::{LayoutElement, Options};
|
||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
|
|||||||
use super::focus_ring::FocusRing;
|
use super::focus_ring::FocusRing;
|
||||||
use super::{LayoutElement, LayoutElementRenderElement, Options};
|
use super::{LayoutElement, LayoutElementRenderElement, Options};
|
||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
|
|
||||||
/// Toplevel window with decorations.
|
/// Toplevel window with decorations.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use super::tile::{Tile, TileRenderElement};
|
|||||||
use super::{LayoutElement, Options};
|
use super::{LayoutElement, Options};
|
||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
+1
-1
@@ -101,7 +101,7 @@ use crate::ipc::server::IpcServer;
|
|||||||
use crate::layout::{Layout, MonitorRenderElement};
|
use crate::layout::{Layout, MonitorRenderElement};
|
||||||
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
||||||
use crate::pw_utils::{Cast, PipeWire};
|
use crate::pw_utils::{Cast, PipeWire};
|
||||||
use crate::render_helpers::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
|
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
center, get_monotonic_time, make_screenshot_path, output_size, write_png_rgba8,
|
center, get_monotonic_time, make_screenshot_path, output_size, write_png_rgba8,
|
||||||
|
|||||||
@@ -1,295 +0,0 @@
|
|||||||
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, ImportMem, Offscreen, Renderer, Texture,
|
|
||||||
};
|
|
||||||
use smithay::utils::{Buffer, Physical, Rectangle, Scale, Transform};
|
|
||||||
|
|
||||||
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
|
||||||
|
|
||||||
/// Trait with our main renderer requirements to save on the typing.
|
|
||||||
pub trait NiriRenderer:
|
|
||||||
ImportAll
|
|
||||||
+ ImportMem
|
|
||||||
+ 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 + ImportMem + 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'render, 'alloc> AsGlesRenderer for TtyRenderer<'render, 'alloc> {
|
|
||||||
fn as_gles_renderer(&mut self) -> &mut GlesRenderer {
|
|
||||||
self.as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'render, 'alloc, 'frame> AsGlesFrame<'frame> for TtyFrame<'render, 'alloc, 'frame> {
|
|
||||||
fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame> {
|
|
||||||
self.as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to implement RenderElement manually due to AsGlesFrame requirement.
|
|
||||||
// This macro does it for us.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! niri_render_elements {
|
|
||||||
($name:ident => { $($variant:ident = $type:ty),+ $(,)? }) => {
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum $name<R: $crate::render_helpers::NiriRenderer> {
|
|
||||||
$($variant($type)),+
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: $crate::render_helpers::NiriRenderer> smithay::backend::renderer::element::Element for $name<R> {
|
|
||||||
fn id(&self) -> &smithay::backend::renderer::element::Id {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.id()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.current_commit()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn geometry(&self, scale: smithay::utils::Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.geometry(scale)),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform(&self) -> smithay::utils::Transform {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.transform()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn src(&self) -> smithay::utils::Rectangle<f64, smithay::utils::Buffer> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.src()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn damage_since(
|
|
||||||
&self,
|
|
||||||
scale: smithay::utils::Scale<f64>,
|
|
||||||
commit: Option<smithay::backend::renderer::utils::CommitCounter>,
|
|
||||||
) -> Vec<smithay::utils::Rectangle<i32, smithay::utils::Physical>> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.damage_since(scale, commit)),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opaque_regions(&self, scale: smithay::utils::Scale<f64>) -> Vec<smithay::utils::Rectangle<i32, smithay::utils::Physical>> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.opaque_regions(scale)),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alpha(&self) -> f32 {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.alpha()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn kind(&self) -> smithay::backend::renderer::element::Kind {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.kind()),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl smithay::backend::renderer::element::RenderElement<smithay::backend::renderer::gles::GlesRenderer> for $name<smithay::backend::renderer::gles::GlesRenderer> {
|
|
||||||
fn draw(
|
|
||||||
&self,
|
|
||||||
frame: &mut smithay::backend::renderer::gles::GlesFrame<'_>,
|
|
||||||
src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>,
|
|
||||||
dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>,
|
|
||||||
damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>],
|
|
||||||
) -> Result<(), smithay::backend::renderer::gles::GlesError> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => {
|
|
||||||
smithay::backend::renderer::element::RenderElement::<smithay::backend::renderer::gles::GlesRenderer>::draw(elem, frame, src, dst, damage)
|
|
||||||
})+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn underlying_storage(&self, renderer: &mut smithay::backend::renderer::gles::GlesRenderer) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'render, 'alloc> smithay::backend::renderer::element::RenderElement<$crate::backend::tty::TtyRenderer<'render, 'alloc>>
|
|
||||||
for $name<$crate::backend::tty::TtyRenderer<'render, 'alloc>>
|
|
||||||
{
|
|
||||||
fn draw(
|
|
||||||
&self,
|
|
||||||
frame: &mut $crate::backend::tty::TtyFrame<'render, 'alloc, '_>,
|
|
||||||
src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>,
|
|
||||||
dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>,
|
|
||||||
damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>],
|
|
||||||
) -> Result<(), $crate::backend::tty::TtyRendererError<'render, 'alloc>> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => {
|
|
||||||
smithay::backend::renderer::element::RenderElement::<$crate::backend::tty::TtyRenderer<'render, 'alloc>>::draw(elem, frame, src, dst, damage)
|
|
||||||
})+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn underlying_storage(
|
|
||||||
&self,
|
|
||||||
renderer: &mut $crate::backend::tty::TtyRenderer<'render, 'alloc>,
|
|
||||||
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
|
|
||||||
match self {
|
|
||||||
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(impl<R: $crate::render_helpers::NiriRenderer> From<$type> for $name<R> {
|
|
||||||
fn from(x: $type) -> Self {
|
|
||||||
Self::$variant(x)
|
|
||||||
}
|
|
||||||
})+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>>
|
|
||||||
for PrimaryGpuTextureRenderElement
|
|
||||||
{
|
|
||||||
fn draw(
|
|
||||||
&self,
|
|
||||||
frame: &mut TtyFrame<'_, '_, '_>,
|
|
||||||
src: Rectangle<f64, Buffer>,
|
|
||||||
dst: Rectangle<i32, Physical>,
|
|
||||||
damage: &[Rectangle<i32, Physical>],
|
|
||||||
) -> Result<(), TtyRendererError<'render, 'alloc>> {
|
|
||||||
let gles_frame = frame.as_gles_frame();
|
|
||||||
RenderElement::<GlesRenderer>::draw(&self.0, gles_frame, src, dst, damage)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn underlying_storage(
|
|
||||||
&self,
|
|
||||||
_renderer: &mut TtyRenderer<'render, 'alloc>,
|
|
||||||
) -> Option<UnderlyingStorage> {
|
|
||||||
// If scanout for things other than Wayland buffers is implemented, this will need to take
|
|
||||||
// the target GPU into account.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod primary_gpu_texture;
|
||||||
|
pub mod render_elements;
|
||||||
|
pub mod renderer;
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
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::utils::{Buffer, Physical, Rectangle, Scale, Transform};
|
||||||
|
|
||||||
|
use super::renderer::AsGlesFrame;
|
||||||
|
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>>
|
||||||
|
for PrimaryGpuTextureRenderElement
|
||||||
|
{
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
frame: &mut TtyFrame<'_, '_, '_>,
|
||||||
|
src: Rectangle<f64, Buffer>,
|
||||||
|
dst: Rectangle<i32, Physical>,
|
||||||
|
damage: &[Rectangle<i32, Physical>],
|
||||||
|
) -> Result<(), TtyRendererError<'render, 'alloc>> {
|
||||||
|
let gles_frame = frame.as_gles_frame();
|
||||||
|
RenderElement::<GlesRenderer>::draw(&self.0, gles_frame, src, dst, damage)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn underlying_storage(
|
||||||
|
&self,
|
||||||
|
_renderer: &mut TtyRenderer<'render, 'alloc>,
|
||||||
|
) -> Option<UnderlyingStorage> {
|
||||||
|
// If scanout for things other than Wayland buffers is implemented, this will need to take
|
||||||
|
// the target GPU into account.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
// We need to implement RenderElement manually due to AsGlesFrame requirement.
|
||||||
|
// This macro does it for us.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! niri_render_elements {
|
||||||
|
($name:ident => { $($variant:ident = $type:ty),+ $(,)? }) => {
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum $name<R: $crate::render_helpers::renderer::NiriRenderer> {
|
||||||
|
$($variant($type)),+
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: $crate::render_helpers::renderer::NiriRenderer> smithay::backend::renderer::element::Element for $name<R> {
|
||||||
|
fn id(&self) -> &smithay::backend::renderer::element::Id {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.id()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.current_commit()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn geometry(&self, scale: smithay::utils::Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.geometry(scale)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform(&self) -> smithay::utils::Transform {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.transform()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn src(&self) -> smithay::utils::Rectangle<f64, smithay::utils::Buffer> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.src()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn damage_since(
|
||||||
|
&self,
|
||||||
|
scale: smithay::utils::Scale<f64>,
|
||||||
|
commit: Option<smithay::backend::renderer::utils::CommitCounter>,
|
||||||
|
) -> Vec<smithay::utils::Rectangle<i32, smithay::utils::Physical>> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.damage_since(scale, commit)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opaque_regions(&self, scale: smithay::utils::Scale<f64>) -> Vec<smithay::utils::Rectangle<i32, smithay::utils::Physical>> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.opaque_regions(scale)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alpha(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.alpha()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kind(&self) -> smithay::backend::renderer::element::Kind {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.kind()),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl smithay::backend::renderer::element::RenderElement<smithay::backend::renderer::gles::GlesRenderer> for $name<smithay::backend::renderer::gles::GlesRenderer> {
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
frame: &mut smithay::backend::renderer::gles::GlesFrame<'_>,
|
||||||
|
src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>,
|
||||||
|
dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>,
|
||||||
|
damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>],
|
||||||
|
) -> Result<(), smithay::backend::renderer::gles::GlesError> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => {
|
||||||
|
smithay::backend::renderer::element::RenderElement::<smithay::backend::renderer::gles::GlesRenderer>::draw(elem, frame, src, dst, damage)
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn underlying_storage(&self, renderer: &mut smithay::backend::renderer::gles::GlesRenderer) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'render, 'alloc> smithay::backend::renderer::element::RenderElement<$crate::backend::tty::TtyRenderer<'render, 'alloc>>
|
||||||
|
for $name<$crate::backend::tty::TtyRenderer<'render, 'alloc>>
|
||||||
|
{
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
frame: &mut $crate::backend::tty::TtyFrame<'render, 'alloc, '_>,
|
||||||
|
src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>,
|
||||||
|
dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>,
|
||||||
|
damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>],
|
||||||
|
) -> Result<(), $crate::backend::tty::TtyRendererError<'render, 'alloc>> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => {
|
||||||
|
smithay::backend::renderer::element::RenderElement::<$crate::backend::tty::TtyRenderer<'render, 'alloc>>::draw(elem, frame, src, dst, damage)
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn underlying_storage(
|
||||||
|
&self,
|
||||||
|
renderer: &mut $crate::backend::tty::TtyRenderer<'render, 'alloc>,
|
||||||
|
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
|
||||||
|
match self {
|
||||||
|
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(impl<R: $crate::render_helpers::renderer::NiriRenderer> From<$type> for $name<R> {
|
||||||
|
fn from(x: $type) -> Self {
|
||||||
|
Self::$variant(x)
|
||||||
|
}
|
||||||
|
})+
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
use smithay::backend::allocator::dmabuf::Dmabuf;
|
||||||
|
use smithay::backend::renderer::gles::{GlesFrame, GlesRenderer, GlesTexture};
|
||||||
|
use smithay::backend::renderer::{
|
||||||
|
Bind, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, Texture,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::backend::tty::{TtyFrame, TtyRenderer};
|
||||||
|
|
||||||
|
/// Trait with our main renderer requirements to save on the typing.
|
||||||
|
pub trait NiriRenderer:
|
||||||
|
ImportAll
|
||||||
|
+ ImportMem
|
||||||
|
+ 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 + ImportMem + 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'render, 'alloc> AsGlesRenderer for TtyRenderer<'render, 'alloc> {
|
||||||
|
fn as_gles_renderer(&mut self) -> &mut GlesRenderer {
|
||||||
|
self.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'render, 'alloc, 'frame> AsGlesFrame<'frame> for TtyFrame<'render, 'alloc, 'frame> {
|
||||||
|
fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame> {
|
||||||
|
self.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ use smithay::output::{Output, WeakOutput};
|
|||||||
use smithay::utils::{Buffer, Physical, Point, Rectangle, Scale, Size, Transform};
|
use smithay::utils::{Buffer, Physical, Point, Rectangle, Scale, Size, Transform};
|
||||||
|
|
||||||
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
||||||
use crate::render_helpers::PrimaryGpuTextureRenderElement;
|
use crate::render_helpers::primary_gpu_texture::PrimaryGpuTextureRenderElement;
|
||||||
|
|
||||||
const BORDER: i32 = 2;
|
const BORDER: i32 = 2;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user