mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-13 08:01:05 +01:00
render: Use custom render element macro
This commit is contained in:
parent
4095abadf3
commit
a251c96278
7 changed files with 411 additions and 8 deletions
|
@ -108,7 +108,7 @@ const SUPPORTED_FORMATS: &[Fourcc] = &[
|
|||
const SUPPORTED_FORMATS_8BIT_ONLY: &[Fourcc] = &[Fourcc::Abgr8888, Fourcc::Argb8888];
|
||||
|
||||
/// A [`MultiRenderer`] that uses the [`GbmGlesBackend`].
|
||||
type UdevRenderer<'a> = MultiRenderer<
|
||||
pub type UdevRenderer<'a> = MultiRenderer<
|
||||
'a,
|
||||
'a,
|
||||
GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
|
||||
|
@ -866,6 +866,12 @@ fn render_frame<'a>(
|
|||
}
|
||||
|
||||
impl Udev {
|
||||
pub fn renderer(&mut self) -> UdevRenderer<'_> {
|
||||
self.gpu_manager
|
||||
.single_renderer(&self.primary_gpu)
|
||||
.expect("failed to create multirenderer")
|
||||
}
|
||||
|
||||
/// A GPU was plugged in.
|
||||
fn device_added(
|
||||
&mut self,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
pub mod transaction;
|
||||
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
|
||||
use pinnacle_api_defs::pinnacle::layout::v0alpha1::{layout_request::Geometries, LayoutResponse};
|
||||
|
|
18
src/layout/transaction.rs
Normal file
18
src/layout/transaction.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use smithay::{
|
||||
backend::renderer::gles::GlesTexture,
|
||||
utils::{Logical, Point, Serial},
|
||||
};
|
||||
|
||||
use crate::window::WindowElement;
|
||||
|
||||
pub struct LayoutTransaction {
|
||||
from: Vec<(GlesTexture)>,
|
||||
to: HashMap<WindowElement, PendingLayoutState>,
|
||||
}
|
||||
|
||||
pub struct PendingLayoutState {
|
||||
serial: Serial,
|
||||
loc: Point<i32, Logical>,
|
||||
}
|
|
@ -4,7 +4,10 @@ use std::{ops::Deref, sync::Mutex};
|
|||
|
||||
use smithay::{
|
||||
backend::renderer::{
|
||||
element::{surface::WaylandSurfaceRenderElement, AsRenderElements, RenderElementStates},
|
||||
element::{
|
||||
surface::WaylandSurfaceRenderElement, AsRenderElements, Element, RenderElementStates,
|
||||
},
|
||||
gles::{GlesRenderer, GlesTexture},
|
||||
ImportAll, ImportMem, Renderer, Texture,
|
||||
},
|
||||
desktop::{
|
||||
|
@ -26,21 +29,35 @@ use smithay::{
|
|||
|
||||
use crate::{
|
||||
backend::Backend,
|
||||
pinnacle_render_elements,
|
||||
state::{State, WithState},
|
||||
window::WindowElement,
|
||||
};
|
||||
|
||||
use self::pointer::{PointerElement, PointerRenderElement};
|
||||
use self::{
|
||||
pointer::{PointerElement, PointerRenderElement},
|
||||
texture::CommonTextureRenderElement,
|
||||
};
|
||||
|
||||
pub mod pointer;
|
||||
pub mod render_elements;
|
||||
pub mod texture;
|
||||
|
||||
pub const CLEAR_COLOR: [f32; 4] = [0.6, 0.6, 0.6, 1.0];
|
||||
pub const CLEAR_COLOR_LOCKED: [f32; 4] = [0.2, 0.0, 0.3, 1.0];
|
||||
|
||||
render_elements! {
|
||||
pub OutputRenderElement<R> where R: ImportAll + ImportMem;
|
||||
Surface = WaylandSurfaceRenderElement<R>,
|
||||
Pointer = PointerRenderElement<R>,
|
||||
// render_elements! {
|
||||
// pub OutputRenderElement<R> where R: ImportAll + ImportMem;
|
||||
// Surface = WaylandSurfaceRenderElement<R>,
|
||||
// Pointer = PointerRenderElement<R>,
|
||||
// }
|
||||
|
||||
pinnacle_render_elements! {
|
||||
#[derive(Debug)]
|
||||
pub enum OutputRenderElement<R> {
|
||||
Surface = WaylandSurfaceRenderElement<R>,
|
||||
Pointer = PointerRenderElement<R>,
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> AsRenderElements<R> for WindowElement
|
||||
|
@ -173,7 +190,7 @@ pub fn pointer_render_elements<R>(
|
|||
pointer_element: &PointerElement<<R as Renderer>::TextureId>,
|
||||
) -> Vec<OutputRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll,
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: Clone + 'static,
|
||||
{
|
||||
let mut output_render_elements = Vec::new();
|
||||
|
@ -349,3 +366,32 @@ impl State {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
pub fn render_to_texture(
|
||||
&mut self,
|
||||
window: &WindowElement,
|
||||
scale: f64,
|
||||
) -> Vec<(GlesTexture, Point<i32, Physical>)> {
|
||||
let render_to_texture = |renderer: &mut GlesRenderer, window: &WindowElement| {
|
||||
let elements = window.render_elements::<WaylandSurfaceRenderElement<GlesRenderer>>(
|
||||
renderer,
|
||||
(0, 0).into(),
|
||||
scale.into(),
|
||||
1.0,
|
||||
);
|
||||
|
||||
elements
|
||||
.into_iter()
|
||||
.map(|elem| (elem.texture().clone(), elem.location(scale.into())))
|
||||
.collect()
|
||||
};
|
||||
|
||||
match self {
|
||||
Backend::Winit(winit) => render_to_texture(winit.backend.renderer(), window),
|
||||
Backend::Udev(udev) => render_to_texture(udev.renderer().as_mut(), window),
|
||||
#[cfg(feature = "testing")]
|
||||
Backend::Dummy(_) => Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ impl<T: Texture> PointerElement<T> {
|
|||
}
|
||||
|
||||
render_elements! {
|
||||
#[derive(Debug)]
|
||||
pub PointerRenderElement<R> where R: ImportAll;
|
||||
Surface=WaylandSurfaceRenderElement<R>,
|
||||
Texture=TextureRenderElement<<R as Renderer>::TextureId>,
|
||||
|
|
229
src/render/render_elements.rs
Normal file
229
src/render/render_elements.rs
Normal file
|
@ -0,0 +1,229 @@
|
|||
/// A custom implementation of [`smithay::render_elements`] that is not generic but rather
|
||||
/// implements over the three used renderers.
|
||||
///
|
||||
/// This is needed to allow GlesTextures to be easily rendered on winit and udev.
|
||||
///
|
||||
/// Also idea from Niri. Ya know this whole compositor is slowly inching towards
|
||||
/// being a Niri clone lol
|
||||
#[macro_export]
|
||||
macro_rules! pinnacle_render_elements {
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
$vis:vis enum $name:ident {
|
||||
$($variant:ident = $type:ty),+ $(,)?
|
||||
}
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
$vis enum $name {
|
||||
$($variant($type)),+
|
||||
}
|
||||
|
||||
$(impl From<$type> for $name {
|
||||
fn from(x: $type) -> Self {
|
||||
Self::$variant(x)
|
||||
}
|
||||
})+
|
||||
|
||||
$crate::pinnacle_render_elements! {
|
||||
@impl $name ($name) () => { $($variant = $type),+ }
|
||||
}
|
||||
};
|
||||
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
$vis:vis enum $name:ident<$generic_name:ident> {
|
||||
$($variant:ident = $type:ty),+ $(,)?
|
||||
}
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
$vis enum $name<$generic_name>
|
||||
where
|
||||
$generic_name: ::smithay::backend::renderer::Renderer + ::smithay::backend::renderer::ImportAll + ::smithay::backend::renderer::ImportMem,
|
||||
$generic_name::TextureId: 'static,
|
||||
{
|
||||
$($variant($type)),+
|
||||
}
|
||||
|
||||
$(impl<$generic_name> From<$type> for $name<$generic_name>
|
||||
where
|
||||
$generic_name: ::smithay::backend::renderer::Renderer + ::smithay::backend::renderer::ImportAll + ::smithay::backend::renderer::ImportMem,
|
||||
$generic_name::TextureId: 'static,
|
||||
{
|
||||
fn from(x: $type) -> Self {
|
||||
Self::$variant(x)
|
||||
}
|
||||
})+
|
||||
|
||||
$crate::pinnacle_render_elements! {
|
||||
@impl $name () ($name<$generic_name>) => { $($variant = $type),+ }
|
||||
}
|
||||
};
|
||||
|
||||
(@impl $name:ident ($($name_no_generic:ident)?) ($($name_generic:ident<$generic:ident>)?) => {
|
||||
$($variant:ident = $type:ty),+
|
||||
}) => {
|
||||
impl$(<$generic>)? ::smithay::backend::renderer::element::Element for $name$(<$generic>)?
|
||||
$(where
|
||||
$generic: ::smithay::backend::renderer::Renderer + ::smithay::backend::renderer::ImportAll + ::smithay::backend::renderer::ImportMem,
|
||||
$generic::TextureId: 'static,)?
|
||||
{
|
||||
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>
|
||||
) -> ::smithay::utils::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: ::std::option::Option<::smithay::backend::renderer::utils::CommitCounter>,
|
||||
) -> ::smithay::backend::renderer::utils::DamageSet<i32, ::smithay::utils::Physical> {
|
||||
match self {
|
||||
$($name::$variant(elem) => elem.damage_since(scale, commit)),+
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_regions(
|
||||
&self,
|
||||
scale: ::smithay::utils::Scale<f64>,
|
||||
) -> ::smithay::backend::renderer::utils::OpaqueRegions<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_generic<::smithay::backend::renderer::gles::GlesRenderer>)? $($name_no_generic)?
|
||||
{
|
||||
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>],
|
||||
) -> ::std::result::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
|
||||
) -> ::std::option::Option<::smithay::backend::renderer::element::UnderlyingStorage> {
|
||||
match self {
|
||||
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::smithay::backend::renderer::element::RenderElement<$crate::backend::udev::UdevRenderer<'a>>
|
||||
for $($name_generic<$crate::backend::udev::UdevRenderer<'a>>)? $($name_no_generic)?
|
||||
{
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <$crate::backend::udev::UdevRenderer<'a> as ::smithay::backend::renderer::Renderer>::Frame<'_>,
|
||||
src: ::smithay::utils::Rectangle<f64, ::smithay::utils::Buffer>,
|
||||
dst: ::smithay::utils::Rectangle<i32, ::smithay::utils::Physical>,
|
||||
damage: &[::smithay::utils::Rectangle<i32, ::smithay::utils::Physical>],
|
||||
) -> ::std::result::Result<
|
||||
(),
|
||||
<$crate::backend::udev::UdevRenderer as ::smithay::backend::renderer::Renderer>::Error,
|
||||
> {
|
||||
match self {
|
||||
$($name::$variant(elem) => {
|
||||
::smithay::backend::renderer::element::RenderElement::<
|
||||
$crate::backend::udev::UdevRenderer
|
||||
>::draw(elem, frame, src, dst, damage)
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
fn underlying_storage(
|
||||
&self,
|
||||
renderer: &mut $crate::backend::udev::UdevRenderer<'a>,
|
||||
) -> ::std::option::Option<::smithay::backend::renderer::element::UnderlyingStorage> {
|
||||
match self {
|
||||
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "testing")]
|
||||
impl ::smithay::backend::renderer::element::RenderElement<::smithay::backend::renderer::test::DummyRenderer>
|
||||
for $($name_generic<::smithay::backend::renderer::test::DummyRenderer>)? $($name_no_generic)?
|
||||
{
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <::smithay::backend::renderer::test::DummyRenderer as ::smithay::backend::renderer::Renderer>::Frame<'_>,
|
||||
src: ::smithay::utils::Rectangle<f64, ::smithay::utils::Buffer>,
|
||||
dst: ::smithay::utils::Rectangle<i32, ::smithay::utils::Physical>,
|
||||
damage: &[::smithay::utils::Rectangle<i32, ::smithay::utils::Physical>],
|
||||
) -> ::std::result::Result<
|
||||
(),
|
||||
<::smithay::backend::renderer::test::DummyRenderer as ::smithay::backend::renderer::Renderer>::Error,
|
||||
> {
|
||||
match self {
|
||||
$($name::$variant(elem) => {
|
||||
::smithay::backend::renderer::element::RenderElement::<
|
||||
::smithay::backend::renderer::test::DummyRenderer
|
||||
>::draw(elem, frame, src, dst, damage)
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
fn underlying_storage(
|
||||
&self,
|
||||
renderer: &mut ::smithay::backend::renderer::test::DummyRenderer,
|
||||
) -> ::std::option::Option<::smithay::backend::renderer::element::UnderlyingStorage> {
|
||||
match self {
|
||||
$($name::$variant(elem) => elem.underlying_storage(renderer)),+
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
src/render/texture.rs
Normal file
101
src/render/texture.rs
Normal file
|
@ -0,0 +1,101 @@
|
|||
use smithay::{
|
||||
backend::renderer::{
|
||||
element::{self, texture::TextureRenderElement, Element, RenderElement},
|
||||
gles::{GlesRenderer, GlesTexture},
|
||||
utils::{CommitCounter, DamageSet, OpaqueRegions},
|
||||
Renderer,
|
||||
},
|
||||
utils::{Buffer, Physical, Rectangle, Scale},
|
||||
};
|
||||
|
||||
use crate::backend::udev::UdevRenderer;
|
||||
|
||||
/// TODO: docs
|
||||
pub struct CommonTextureRenderElement(TextureRenderElement<GlesTexture>);
|
||||
|
||||
impl Element for CommonTextureRenderElement {
|
||||
fn id(&self) -> &element::Id {
|
||||
self.0.id()
|
||||
}
|
||||
|
||||
fn current_commit(&self) -> CommitCounter {
|
||||
self.0.current_commit()
|
||||
}
|
||||
|
||||
fn src(&self) -> Rectangle<f64, Buffer> {
|
||||
self.0.src()
|
||||
}
|
||||
|
||||
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||
self.0.geometry(scale)
|
||||
}
|
||||
|
||||
fn location(&self, scale: Scale<f64>) -> smithay::utils::Point<i32, Physical> {
|
||||
self.0.location(scale)
|
||||
}
|
||||
|
||||
fn transform(&self) -> smithay::utils::Transform {
|
||||
self.0.transform()
|
||||
}
|
||||
|
||||
fn damage_since(
|
||||
&self,
|
||||
scale: Scale<f64>,
|
||||
commit: Option<CommitCounter>,
|
||||
) -> DamageSet<i32, Physical> {
|
||||
self.0.damage_since(scale, commit)
|
||||
}
|
||||
|
||||
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> {
|
||||
self.0.opaque_regions(scale)
|
||||
}
|
||||
|
||||
fn alpha(&self) -> f32 {
|
||||
self.0.alpha()
|
||||
}
|
||||
|
||||
fn kind(&self) -> element::Kind {
|
||||
self.0.kind()
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderElement<GlesRenderer> for CommonTextureRenderElement {
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <GlesRenderer as Renderer>::Frame<'_>,
|
||||
src: Rectangle<f64, Buffer>,
|
||||
dst: Rectangle<i32, Physical>,
|
||||
damage: &[Rectangle<i32, Physical>],
|
||||
) -> Result<(), <GlesRenderer as Renderer>::Error> {
|
||||
RenderElement::<GlesRenderer>::draw(&self.0, frame, src, dst, damage)
|
||||
}
|
||||
|
||||
fn underlying_storage(
|
||||
&self,
|
||||
renderer: &mut GlesRenderer,
|
||||
) -> Option<element::UnderlyingStorage<'_>> {
|
||||
let _ = renderer;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RenderElement<UdevRenderer<'a>> for CommonTextureRenderElement {
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <UdevRenderer<'a> as Renderer>::Frame<'_>,
|
||||
src: Rectangle<f64, Buffer>,
|
||||
dst: Rectangle<i32, Physical>,
|
||||
damage: &[Rectangle<i32, Physical>],
|
||||
) -> Result<(), <UdevRenderer<'a> as Renderer>::Error> {
|
||||
RenderElement::<GlesRenderer>::draw(&self.0, frame.as_mut(), src, dst, damage)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn underlying_storage(
|
||||
&self,
|
||||
renderer: &mut UdevRenderer<'a>,
|
||||
) -> Option<element::UnderlyingStorage<'_>> {
|
||||
let _ = renderer;
|
||||
None
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue