renderer: Remove render_texture from Frame

This commit is contained in:
Victor Brekenfeld 2021-10-23 16:12:21 +02:00 committed by Victor Berger
parent 7a7f1217d8
commit 011a7da665
3 changed files with 74 additions and 64 deletions

View File

@ -22,6 +22,7 @@
- All winit backend internal event types now use `WinitInput` as the backend type. - All winit backend internal event types now use `WinitInput` as the backend type.
- `WinitEventLoop::dispatch_new_events` is now used to receive some `WinitEvent`s. - `WinitEventLoop::dispatch_new_events` is now used to receive some `WinitEvent`s.
- Added `TabletToolType::Unknown` as an option for tablet events - Added `TabletToolType::Unknown` as an option for tablet events
- `render_texture` was removed from `Frame`, use `render_texture_at` or `render_texture_from_to` instead or use `Gles2Renderer::render_texture` as a direct replacement.
### Additions ### Additions

View File

@ -11,7 +11,7 @@ use std::sync::{
}; };
use std::{collections::HashSet, os::raw::c_char}; use std::{collections::HashSet, os::raw::c_char};
use cgmath::{prelude::*, Matrix3, Vector2}; use cgmath::{prelude::*, Matrix3, Vector2, Vector3};
mod shaders; mod shaders;
mod version; mod version;
@ -26,7 +26,7 @@ use crate::backend::egl::{
EGLContext, EGLSurface, MakeCurrentError, EGLContext, EGLSurface, MakeCurrentError,
}; };
use crate::backend::SwapBuffersError; use crate::backend::SwapBuffersError;
use crate::utils::{Buffer, Physical, Size}; use crate::utils::{Buffer, Physical, Rectangle, Size};
#[cfg(all(feature = "wayland_frontend", feature = "use_system_lib"))] #[cfg(all(feature = "wayland_frontend", feature = "use_system_lib"))]
use super::ImportEgl; use super::ImportEgl;
@ -35,8 +35,6 @@ use super::{ImportDma, ImportShm};
#[cfg(all(feature = "wayland_frontend", feature = "use_system_lib"))] #[cfg(all(feature = "wayland_frontend", feature = "use_system_lib"))]
use crate::backend::egl::{display::EGLBufferReader, Format as EGLFormat}; use crate::backend::egl::{display::EGLBufferReader, Format as EGLFormat};
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
use crate::utils::Rectangle;
#[cfg(feature = "wayland_frontend")]
use wayland_server::protocol::{wl_buffer, wl_shm}; use wayland_server::protocol::{wl_buffer, wl_shm};
use slog::{debug, error, info, o, trace, warn}; use slog::{debug, error, info, o, trace, warn};
@ -515,8 +513,8 @@ impl Gles2Renderer {
logger: log, logger: log,
_not_send: std::ptr::null_mut(), _not_send: std::ptr::null_mut(),
}; };
renderer.downscale_filter(TextureFilter::Nearest); renderer.downscale_filter(TextureFilter::Nearest)?;
renderer.upscale_filter(TextureFilter::Linear); renderer.upscale_filter(TextureFilter::Linear)?;
renderer.egl.unbind()?; renderer.egl.unbind()?;
Ok(renderer) Ok(renderer)
} }
@ -1013,25 +1011,32 @@ impl Renderer for Gles2Renderer {
fn downscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> { fn downscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> {
self.make_current()?; self.make_current()?;
unsafe { unsafe {
self.gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_MIN_FILTER, match filter { self.gl.TexParameteri(
TextureFilter::Nearest => ffi::NEAREST as i32, ffi::TEXTURE_2D,
TextureFilter::Linear => ffi::LINEAR as i32, ffi::TEXTURE_MIN_FILTER,
}); match filter {
TextureFilter::Nearest => ffi::NEAREST as i32,
TextureFilter::Linear => ffi::LINEAR as i32,
},
);
} }
Ok(()) Ok(())
} }
fn upscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> { fn upscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> {
self.make_current()?; self.make_current()?;
unsafe { unsafe {
self.gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_MAG_FILTER, match filter { self.gl.TexParameteri(
TextureFilter::Nearest => ffi::NEAREST as i32, ffi::TEXTURE_2D,
TextureFilter::Linear => ffi::LINEAR as i32, ffi::TEXTURE_MAG_FILTER,
}); match filter {
TextureFilter::Nearest => ffi::NEAREST as i32,
TextureFilter::Linear => ffi::LINEAR as i32,
},
);
} }
Ok(()) Ok(())
} }
fn render<F, R>( fn render<F, R>(
&mut self, &mut self,
size: Size<i32, Physical>, size: Size<i32, Physical>,
@ -1125,13 +1130,60 @@ impl Frame for Gles2Frame {
Ok(()) Ok(())
} }
fn render_texture( fn render_texture_from_to(
&mut self, &mut self,
tex: &Self::TextureId, texture: &Self::TextureId,
src: Rectangle<i32, Buffer>,
dest: Rectangle<f64, Physical>,
transform: Transform,
alpha: f32,
) -> Result<(), Self::Error> {
let mut mat = Matrix3::<f32>::identity();
// position and scale
mat = mat * Matrix3::from_translation(Vector2::new(dest.loc.x as f32, dest.loc.y as f32));
mat = mat * Matrix3::from_nonuniform_scale(dest.size.w as f32, dest.size.h as f32);
//apply surface transformation
mat = mat * Matrix3::from_translation(Vector2::new(0.5, 0.5));
if transform == Transform::Normal {
assert_eq!(mat, mat * transform.invert().matrix());
assert_eq!(transform.matrix(), Matrix3::<f32>::identity());
}
mat = mat * transform.invert().matrix();
mat = mat * Matrix3::from_translation(Vector2::new(-0.5, -0.5));
// this matrix should be regular, we can expect invert to succeed
let tex_size = texture.size();
let texture_mat = Matrix3::from_nonuniform_scale(tex_size.w as f32, tex_size.h as f32)
.invert()
.unwrap();
let verts = [
(texture_mat * Vector3::new((src.loc.x + src.size.w) as f32, src.loc.y as f32, 0.0)).truncate(), // top-right
(texture_mat * Vector3::new(src.loc.x as f32, src.loc.y as f32, 0.0)).truncate(), // top-left
(texture_mat
* Vector3::new(
(src.loc.x + src.size.w) as f32,
(src.loc.y + src.size.h) as f32,
0.0,
))
.truncate(), // bottom-right
(texture_mat * Vector3::new(src.loc.x as f32, (src.loc.y + src.size.h) as f32, 0.0)).truncate(), // bottom-left
];
self.render_texture(texture, mat, verts, alpha)
}
}
impl Gles2Frame {
/// Render a texture to the current target using given projection matrix and alpha.
/// The given vertices are used to source the texture. This is mostly useful for cropping the texture.
pub fn render_texture(
&mut self,
tex: &Gles2Texture,
mut matrix: Matrix3<f32>, mut matrix: Matrix3<f32>,
tex_coords: [Vector2<f32>; 4], tex_coords: [Vector2<f32>; 4],
alpha: f32, alpha: f32,
) -> Result<(), Self::Error> { ) -> Result<(), Gles2Error> {
//apply output transformation //apply output transformation
matrix = self.current_projection * matrix; matrix = self.current_projection * matrix;

View File

@ -14,7 +14,7 @@ use crate::utils::{Buffer, Physical, Point, Rectangle, Size};
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
use crate::wayland::compositor::SurfaceData; use crate::wayland::compositor::SurfaceData;
use cgmath::{prelude::*, Matrix3, Vector2, Vector3}; use cgmath::Matrix3;
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
use wayland_server::protocol::{wl_buffer, wl_shm}; use wayland_server::protocol::{wl_buffer, wl_shm};
@ -172,15 +172,6 @@ pub trait Frame {
/// This operation is only valid in between a `begin` and `finish`-call. /// This operation is only valid in between a `begin` and `finish`-call.
/// If called outside this operation may error-out, do nothing or modify future rendering results in any way. /// If called outside this operation may error-out, do nothing or modify future rendering results in any way.
fn clear(&mut self, color: [f32; 4]) -> Result<(), Self::Error>; fn clear(&mut self, color: [f32; 4]) -> Result<(), Self::Error>;
/// Render a texture to the current target using given projection matrix and alpha.
/// The given vertices are used to source the texture. This is mostly useful for cropping the texture.
fn render_texture(
&mut self,
texture: &Self::TextureId,
matrix: Matrix3<f32>,
tex_coords: [Vector2<f32>; 4],
alpha: f32,
) -> Result<(), Self::Error>;
/// Render a texture to the current target as a flat 2d-plane at a given /// Render a texture to the current target as a flat 2d-plane at a given
/// position and applying the given transformation with the given alpha value. /// position and applying the given transformation with the given alpha value.
@ -218,41 +209,7 @@ pub trait Frame {
dest: Rectangle<f64, Physical>, dest: Rectangle<f64, Physical>,
transform: Transform, transform: Transform,
alpha: f32, alpha: f32,
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error>;
let mut mat = Matrix3::<f32>::identity();
// position and scale
mat = mat * Matrix3::from_translation(Vector2::new(dest.loc.x as f32, dest.loc.y as f32));
mat = mat * Matrix3::from_nonuniform_scale(dest.size.w as f32, dest.size.h as f32);
//apply surface transformation
mat = mat * Matrix3::from_translation(Vector2::new(0.5, 0.5));
if transform == Transform::Normal {
assert_eq!(mat, mat * transform.invert().matrix());
assert_eq!(transform.matrix(), Matrix3::<f32>::identity());
}
mat = mat * transform.invert().matrix();
mat = mat * Matrix3::from_translation(Vector2::new(-0.5, -0.5));
// this matrix should be regular, we can expect invert to succeed
let tex_size = texture.size();
let texture_mat = Matrix3::from_nonuniform_scale(tex_size.w as f32, tex_size.h as f32)
.invert()
.unwrap();
let verts = [
(texture_mat * Vector3::new((src.loc.x + src.size.w) as f32, src.loc.y as f32, 0.0)).truncate(), // top-right
(texture_mat * Vector3::new(src.loc.x as f32, src.loc.y as f32, 0.0)).truncate(), // top-left
(texture_mat
* Vector3::new(
(src.loc.x + src.size.w) as f32,
(src.loc.y + src.size.h) as f32,
0.0,
))
.truncate(), // bottom-right
(texture_mat * Vector3::new(src.loc.x as f32, (src.loc.y + src.size.h) as f32, 0.0)).truncate(), // bottom-left
];
self.render_texture(texture, mat, verts, alpha)
}
} }
/// Abstraction of commonly used rendering operations for compositors. /// Abstraction of commonly used rendering operations for compositors.