Skip to content

Commit 332aa42

Browse files
committed
backend: add auto renderer
1 parent 31e4d48 commit 332aa42

14 files changed

+1274
-1
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pkg-config = { version = "0.3.17", optional = true }
8484
cc = { version = "1.0.79", optional = true }
8585

8686
[features]
87-
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_libseat", "backend_x11", "backend_winit", "desktop", "renderer_gl", "renderer_pixman", "renderer_multi", "xwayland", "wayland_frontend", "backend_vulkan"]
87+
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_libseat", "backend_x11", "backend_winit", "desktop", "renderer_gl", "renderer_pixman", "renderer_auto", "renderer_multi", "xwayland", "wayland_frontend", "backend_vulkan"]
8888
backend_winit = ["winit", "backend_egl", "wayland-client", "wayland-cursor", "wayland-egl", "renderer_gl"]
8989
backend_x11 = ["x11rb", "x11rb/dri3", "x11rb/xfixes", "x11rb/xinput", "x11rb/present", "x11rb_event_source", "backend_gbm", "backend_drm", "backend_egl"]
9090
backend_drm = ["drm", "drm-ffi"]
@@ -102,6 +102,7 @@ renderer_gl = ["gl_generator", "backend_egl"]
102102
renderer_glow = ["renderer_gl", "glow"]
103103
renderer_multi = ["backend_drm", "aliasable"]
104104
renderer_pixman = ["pixman"]
105+
renderer_auto = []
105106
renderer_test = []
106107
use_system_lib = ["wayland_frontend", "wayland-backend/server_system", "wayland-sys", "gbm?/import-wayland"]
107108
use_bindgen = ["drm-ffi/use_bindgen", "gbm/use_bindgen", "input/use_bindgen"]

src/backend/renderer/auto/bind.rs

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use crate::backend::{
2+
allocator::{dmabuf::Dmabuf, format::FormatSet},
3+
renderer::Bind,
4+
};
5+
6+
#[cfg(feature = "renderer_gl")]
7+
use crate::backend::{
8+
egl::EGLSurface,
9+
renderer::gles::{GlesRenderbuffer, GlesTexture},
10+
};
11+
12+
#[cfg(feature = "renderer_pixman")]
13+
use pixman::Image;
14+
15+
use super::{AutoRenderer, AutoRendererError, AutoRendererTarget};
16+
17+
impl Bind<Dmabuf> for AutoRenderer {
18+
fn bind<'a>(&mut self, target: &'a mut Dmabuf) -> Result<Self::Framebuffer<'a>, Self::Error> {
19+
match self {
20+
#[cfg(feature = "renderer_gl")]
21+
AutoRenderer::Gles(renderer) => Bind::<Dmabuf>::bind(renderer, target)
22+
.map(AutoRendererTarget::from)
23+
.map_err(AutoRendererError::from),
24+
#[cfg(feature = "renderer_pixman")]
25+
AutoRenderer::Pixman(renderer) => Bind::<Dmabuf>::bind(renderer, target)
26+
.map(AutoRendererTarget::from)
27+
.map_err(AutoRendererError::from),
28+
}
29+
}
30+
31+
fn supported_formats(&self) -> Option<FormatSet> {
32+
match self {
33+
#[cfg(feature = "renderer_gl")]
34+
AutoRenderer::Gles(renderer) => Bind::<Dmabuf>::supported_formats(renderer),
35+
#[cfg(feature = "renderer_pixman")]
36+
AutoRenderer::Pixman(renderer) => Bind::<Dmabuf>::supported_formats(renderer),
37+
}
38+
}
39+
}
40+
41+
#[cfg(feature = "renderer_gl")]
42+
impl Bind<EGLSurface> for AutoRenderer {
43+
fn bind<'a>(&mut self, target: &'a mut EGLSurface) -> Result<Self::Framebuffer<'a>, Self::Error> {
44+
let AutoRenderer::Gles(renderer) = self else {
45+
return Err(AutoRendererError::Unsupported);
46+
};
47+
Bind::<EGLSurface>::bind(renderer, target)
48+
.map(AutoRendererTarget::from)
49+
.map_err(AutoRendererError::from)
50+
}
51+
52+
fn supported_formats(&self) -> Option<FormatSet> {
53+
let AutoRenderer::Gles(renderer) = self else {
54+
return None;
55+
};
56+
Bind::<Dmabuf>::supported_formats(renderer)
57+
}
58+
}
59+
60+
#[cfg(feature = "renderer_gl")]
61+
impl Bind<GlesTexture> for AutoRenderer {
62+
fn bind<'a>(&mut self, target: &'a mut GlesTexture) -> Result<Self::Framebuffer<'a>, Self::Error> {
63+
let AutoRenderer::Gles(renderer) = self else {
64+
return Err(AutoRendererError::Unsupported);
65+
};
66+
Bind::<GlesTexture>::bind(renderer, target)
67+
.map(AutoRendererTarget::from)
68+
.map_err(AutoRendererError::from)
69+
}
70+
71+
fn supported_formats(&self) -> Option<FormatSet> {
72+
let AutoRenderer::Gles(renderer) = self else {
73+
return None;
74+
};
75+
Bind::<GlesTexture>::supported_formats(renderer)
76+
}
77+
}
78+
79+
#[cfg(feature = "renderer_gl")]
80+
impl Bind<GlesRenderbuffer> for AutoRenderer {
81+
fn bind<'a>(&mut self, target: &'a mut GlesRenderbuffer) -> Result<Self::Framebuffer<'a>, Self::Error> {
82+
let AutoRenderer::Gles(renderer) = self else {
83+
return Err(AutoRendererError::Unsupported);
84+
};
85+
Bind::<GlesRenderbuffer>::bind(renderer, target)
86+
.map(AutoRendererTarget::from)
87+
.map_err(AutoRendererError::from)
88+
}
89+
90+
fn supported_formats(&self) -> Option<FormatSet> {
91+
let AutoRenderer::Gles(renderer) = self else {
92+
return None;
93+
};
94+
Bind::<GlesRenderbuffer>::supported_formats(renderer)
95+
}
96+
}
97+
98+
#[cfg(feature = "renderer_gl")]
99+
impl Bind<Image<'static, 'static>> for AutoRenderer {
100+
fn bind<'a>(
101+
&mut self,
102+
target: &'a mut Image<'static, 'static>,
103+
) -> Result<Self::Framebuffer<'a>, Self::Error> {
104+
let AutoRenderer::Pixman(renderer) = self else {
105+
return Err(AutoRendererError::Unsupported);
106+
};
107+
Bind::<Image<'static, 'static>>::bind(renderer, target)
108+
.map(AutoRendererTarget::from)
109+
.map_err(AutoRendererError::from)
110+
}
111+
112+
fn supported_formats(&self) -> Option<FormatSet> {
113+
let AutoRenderer::Pixman(renderer) = self else {
114+
return None;
115+
};
116+
Bind::<Image<'static, 'static>>::supported_formats(renderer)
117+
}
118+
}

src/backend/renderer/auto/blit.rs

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use crate::{
2+
backend::renderer::{Blit, BlitFrame, TextureFilter},
3+
utils::{Physical, Rectangle},
4+
};
5+
6+
#[cfg(feature = "renderer_gl")]
7+
use crate::backend::renderer::gles::GlesTarget;
8+
9+
use super::{AutoRenderer, AutoRendererError, AutoRendererFrame};
10+
11+
impl Blit for AutoRenderer {
12+
fn blit(
13+
&mut self,
14+
from: &Self::Framebuffer<'_>,
15+
to: &mut Self::Framebuffer<'_>,
16+
src: Rectangle<i32, Physical>,
17+
dst: Rectangle<i32, Physical>,
18+
filter: crate::backend::renderer::TextureFilter,
19+
) -> Result<(), Self::Error> {
20+
match self {
21+
#[cfg(feature = "renderer_gl")]
22+
AutoRenderer::Gles(renderer) => {
23+
Blit::blit(renderer, from.try_into()?, to.try_into()?, src, dst, filter)
24+
.map_err(AutoRendererError::from)
25+
}
26+
#[cfg(feature = "renderer_pixman")]
27+
AutoRenderer::Pixman(_) => return Err(AutoRendererError::Unsupported),
28+
}
29+
}
30+
}
31+
32+
impl<'frame, 'buffer> BlitFrame<GlesTarget<'buffer>> for AutoRendererFrame<'frame, 'buffer> {
33+
fn blit_to(
34+
&mut self,
35+
to: &mut GlesTarget<'buffer>,
36+
src: Rectangle<i32, Physical>,
37+
dst: Rectangle<i32, Physical>,
38+
filter: TextureFilter,
39+
) -> Result<(), Self::Error> {
40+
match self {
41+
#[cfg(feature = "renderer_gl")]
42+
AutoRendererFrame::Gles(renderer) => {
43+
BlitFrame::blit_to(renderer, to, src, dst, filter).map_err(AutoRendererError::from)
44+
}
45+
#[cfg(feature = "renderer_pixman")]
46+
AutoRendererFrame::Pixman(_) => return Err(AutoRendererError::Unsupported),
47+
}
48+
}
49+
50+
fn blit_from(
51+
&mut self,
52+
from: &GlesTarget<'buffer>,
53+
src: Rectangle<i32, Physical>,
54+
dst: Rectangle<i32, Physical>,
55+
filter: TextureFilter,
56+
) -> Result<(), Self::Error> {
57+
match self {
58+
#[cfg(feature = "renderer_gl")]
59+
AutoRendererFrame::Gles(renderer) => {
60+
BlitFrame::blit_from(renderer, from, src, dst, filter).map_err(AutoRendererError::from)
61+
}
62+
#[cfg(feature = "renderer_pixman")]
63+
AutoRendererFrame::Pixman(_) => return Err(AutoRendererError::Unsupported),
64+
}
65+
}
66+
}

src/backend/renderer/auto/error.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#[cfg(feature = "renderer_gl")]
2+
use crate::backend::renderer::gles::GlesError;
3+
#[cfg(feature = "renderer_pixman")]
4+
use crate::backend::renderer::pixman::PixmanError;
5+
6+
/// Error for the auto renderer
7+
#[derive(Debug, thiserror::Error)]
8+
pub enum AutoRendererError {
9+
/// Gles error
10+
#[cfg(feature = "renderer_gl")]
11+
#[error(transparent)]
12+
Gles(GlesError),
13+
/// Pixman error
14+
#[cfg(feature = "renderer_pixman")]
15+
#[error(transparent)]
16+
Pixman(PixmanError),
17+
/// Incompatible resource
18+
#[error("An incompatible resource has been passed")]
19+
IncompatibleResource,
20+
/// Unsupported
21+
#[error("The operation is not supported on this particular renderer")]
22+
Unsupported
23+
}
24+
25+
#[cfg(feature = "renderer_gl")]
26+
impl From<GlesError> for AutoRendererError {
27+
fn from(value: GlesError) -> Self {
28+
Self::Gles(value)
29+
}
30+
}
31+
32+
#[cfg(feature = "renderer_pixman")]
33+
impl From<PixmanError> for AutoRendererError {
34+
fn from(value: PixmanError) -> Self {
35+
Self::Pixman(value)
36+
}
37+
}

src/backend/renderer/auto/export.rs

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use crate::{
2+
backend::renderer::ExportMem,
3+
utils::{Buffer, Rectangle},
4+
};
5+
6+
use super::{AutoRenderer, AutoRendererError, AutoRendererMapping};
7+
8+
impl ExportMem for AutoRenderer {
9+
type TextureMapping = AutoRendererMapping;
10+
11+
fn copy_framebuffer(
12+
&mut self,
13+
target: &Self::Framebuffer<'_>,
14+
region: Rectangle<i32, Buffer>,
15+
format: gbm::Format,
16+
) -> Result<Self::TextureMapping, Self::Error> {
17+
match self {
18+
#[cfg(feature = "renderer_gl")]
19+
AutoRenderer::Gles(renderer) => {
20+
ExportMem::copy_framebuffer(renderer, target.try_into()?, region, format)
21+
.map(AutoRendererMapping::from)
22+
.map_err(AutoRendererError::from)
23+
}
24+
#[cfg(feature = "renderer_pixman")]
25+
AutoRenderer::Pixman(renderer) => {
26+
ExportMem::copy_framebuffer(renderer, target.try_into()?, region, format)
27+
.map(AutoRendererMapping::from)
28+
.map_err(AutoRendererError::from)
29+
}
30+
}
31+
}
32+
33+
fn copy_texture(
34+
&mut self,
35+
texture: &Self::TextureId,
36+
region: Rectangle<i32, Buffer>,
37+
format: gbm::Format,
38+
) -> Result<Self::TextureMapping, Self::Error> {
39+
match self {
40+
#[cfg(feature = "renderer_gl")]
41+
AutoRenderer::Gles(renderer) => {
42+
ExportMem::copy_texture(renderer, texture.try_into()?, region, format)
43+
.map(AutoRendererMapping::from)
44+
.map_err(AutoRendererError::from)
45+
}
46+
#[cfg(feature = "renderer_pixman")]
47+
AutoRenderer::Pixman(renderer) => {
48+
ExportMem::copy_texture(renderer, texture.try_into()?, region, format)
49+
.map(AutoRendererMapping::from)
50+
.map_err(AutoRendererError::from)
51+
}
52+
}
53+
}
54+
55+
fn can_read_texture(&mut self, texture: &Self::TextureId) -> Result<bool, Self::Error> {
56+
match self {
57+
#[cfg(feature = "renderer_gl")]
58+
AutoRenderer::Gles(renderer) => {
59+
ExportMem::can_read_texture(renderer, texture.try_into()?).map_err(AutoRendererError::from)
60+
}
61+
#[cfg(feature = "renderer_pixman")]
62+
AutoRenderer::Pixman(renderer) => {
63+
ExportMem::can_read_texture(renderer, texture.try_into()?).map_err(AutoRendererError::from)
64+
}
65+
}
66+
}
67+
68+
fn map_texture<'a>(
69+
&mut self,
70+
texture_mapping: &'a Self::TextureMapping,
71+
) -> Result<&'a [u8], Self::Error> {
72+
match self {
73+
#[cfg(feature = "renderer_gl")]
74+
AutoRenderer::Gles(renderer) => {
75+
ExportMem::map_texture(renderer, texture_mapping.try_into()?).map_err(AutoRendererError::from)
76+
}
77+
#[cfg(feature = "renderer_pixman")]
78+
AutoRenderer::Pixman(renderer) => {
79+
ExportMem::map_texture(renderer, texture_mapping.try_into()?).map_err(AutoRendererError::from)
80+
}
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)