aboutsummaryrefslogtreecommitdiff
path: root/niri-visual-tests/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-03-09 22:03:14 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-03-10 07:59:14 +0300
commit1c521e48313b42d2e314d139c3cf4ac5dc44e7a7 (patch)
treeef1b83079f489c3432b3b430250e7cbc103ea6f8 /niri-visual-tests/src
parenteda43b2b935b75f3e8d2041be1bd25413787b1c3 (diff)
downloadniri-1c521e48313b42d2e314d139c3cf4ac5dc44e7a7.tar.gz
niri-1c521e48313b42d2e314d139c3cf4ac5dc44e7a7.tar.bz2
niri-1c521e48313b42d2e314d139c3cf4ac5dc44e7a7.zip
Update Smithay (Framebuffer type)
Diffstat (limited to 'niri-visual-tests/src')
-rw-r--r--niri-visual-tests/src/smithay_view.rs96
-rw-r--r--niri-visual-tests/src/test_window.rs2
2 files changed, 57 insertions, 41 deletions
diff --git a/niri-visual-tests/src/smithay_view.rs b/niri-visual-tests/src/smithay_view.rs
index 7b8e77ee..1820ca45 100644
--- a/niri-visual-tests/src/smithay_view.rs
+++ b/niri-visual-tests/src/smithay_view.rs
@@ -17,19 +17,25 @@ mod imp {
use niri::render_helpers::{resources, shaders};
use smithay::backend::egl::ffi::egl;
use smithay::backend::egl::EGLContext;
- use smithay::backend::renderer::gles::GlesRenderer;
- use smithay::backend::renderer::{Color32F, Frame, Renderer, Unbind};
+ use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
+ use smithay::backend::renderer::{Bind, Color32F, Frame, Offscreen, Renderer};
+ use smithay::reexports::gbm::Format as Fourcc;
use smithay::utils::{Physical, Rectangle, Scale, Transform};
use super::*;
type DynMakeTestCase = Box<dyn Fn(Args) -> Box<dyn TestCase>>;
+ struct RendererData {
+ renderer: GlesRenderer,
+ dummy_texture: GlesTexture,
+ }
+
#[derive(Default)]
pub struct SmithayView {
gl_area: gtk::GLArea,
size: Cell<(i32, i32)>,
- renderer: RefCell<Option<Result<GlesRenderer, ()>>>,
+ renderer: RefCell<Option<Result<RendererData, ()>>>,
pub make_test_case: OnceCell<DynMakeTestCase>,
test_case: RefCell<Option<Box<dyn TestCase>>>,
pub clock: RefCell<Clock>,
@@ -125,6 +131,10 @@ mod imp {
let Ok(renderer) = renderer else {
return Ok(());
};
+ let RendererData {
+ renderer,
+ dummy_texture,
+ } = renderer;
let size = self.size.get();
@@ -147,16 +157,45 @@ mod imp {
let rect: Rectangle<i32, Physical> = Rectangle::from_size(Size::from(size));
- let elements = unsafe {
- with_framebuffer_save_restore(renderer, |renderer| {
- case.render(renderer, Size::from(size))
+ // Fetch GtkGLArea's framebuffer binding.
+ let mut framebuffer = 0;
+ renderer
+ .with_context(|gl| unsafe {
+ gl.GetIntegerv(
+ smithay::backend::renderer::gles::ffi::FRAMEBUFFER_BINDING,
+ &mut framebuffer,
+ );
})
- }?;
+ .context("error running closure in GL context")?;
+ ensure!(framebuffer != 0, "error getting the framebuffer");
+
+ // This call will already change the framebuffer binding (offscreen elements will bind
+ // intermediate textures during rendering).
+ let elements = case.render(renderer, Size::from(size));
+
+ // HACK: there's currently no way to "just" render into an externally bound framebuffer
+ // (like we have in this case). The render() call requires a valid target. So what
+ // we'll do is use a dummy texture as a target, then swap the framebuffer binding right
+ // before rendering.
+ let mut dummy_target = renderer
+ .bind(dummy_texture)
+ .context("error binding dummy texture")?;
let mut frame = renderer
- .render(rect.size, Transform::Normal)
+ .render(&mut dummy_target, rect.size, Transform::Normal)
.context("error creating frame")?;
+ // Now that render() bound the dummy texture, change the binding underneath it back to
+ // GtkGLArea's framebuffer, to render there instead.
+ frame
+ .with_context(|gl| unsafe {
+ gl.BindFramebuffer(
+ smithay::backend::renderer::gles::ffi::FRAMEBUFFER,
+ framebuffer as u32,
+ );
+ })
+ .context("error running closure in GL context")?;
+
frame
.clear(Color32F::from([0.3, 0.3, 0.3, 1.]), &[rect])
.context("error clearing")?;
@@ -177,7 +216,7 @@ mod imp {
}
}
- unsafe fn create_renderer() -> anyhow::Result<GlesRenderer> {
+ unsafe fn create_renderer() -> anyhow::Result<RendererData> {
smithay::backend::egl::ffi::make_sure_egl_is_loaded()
.context("error loading EGL symbols in Smithay")?;
@@ -200,40 +239,17 @@ mod imp {
let mut renderer = GlesRenderer::new(egl_context).context("error creating GlesRenderer")?;
+ let dummy_texture = renderer
+ .create_buffer(Fourcc::Abgr8888, Size::from((1, 1)))
+ .context("error creating dummy texture")?;
+
resources::init(&mut renderer);
shaders::init(&mut renderer);
- Ok(renderer)
- }
-
- unsafe fn with_framebuffer_save_restore<T>(
- renderer: &mut GlesRenderer,
- f: impl FnOnce(&mut GlesRenderer) -> T,
- ) -> anyhow::Result<T> {
- let mut framebuffer = 0;
- renderer
- .with_context(|gl| unsafe {
- gl.GetIntegerv(
- smithay::backend::renderer::gles::ffi::FRAMEBUFFER_BINDING,
- &mut framebuffer,
- );
- })
- .context("error running closure in GL context")?;
- ensure!(framebuffer != 0, "error getting the framebuffer");
-
- let rv = f(renderer);
-
- renderer.unbind().context("error unbinding")?;
- renderer
- .with_context(|gl| unsafe {
- gl.BindFramebuffer(
- smithay::backend::renderer::gles::ffi::FRAMEBUFFER,
- framebuffer as u32,
- );
- })
- .context("error running closure in GL context")?;
-
- Ok(rv)
+ Ok(RendererData {
+ renderer,
+ dummy_texture,
+ })
}
}
diff --git a/niri-visual-tests/src/test_window.rs b/niri-visual-tests/src/test_window.rs
index 228701c7..158f8b4b 100644
--- a/niri-visual-tests/src/test_window.rs
+++ b/niri-visual-tests/src/test_window.rs
@@ -11,7 +11,7 @@ use niri::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElemen
use niri::render_helpers::{RenderTarget, SplitElements};
use niri::utils::transaction::Transaction;
use niri::window::ResolvedWindowRules;
-use smithay::backend::renderer::element::{Id, Kind};
+use smithay::backend::renderer::element::Kind;
use smithay::output::{self, Output};
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{Logical, Point, Scale, Serial, Size, Transform};