renderer: Allow to set texture filtering methods

This commit is contained in:
Victor Brekenfeld 2021-10-23 15:58:05 +02:00 committed by Victor Berger
parent 076f824431
commit 7a7f1217d8
3 changed files with 42 additions and 2 deletions

View File

@ -44,6 +44,7 @@
- `KeyState`, `MouseButton`, `ButtonState` and `Axis` in `backend::input` now derive `Hash`. - `KeyState`, `MouseButton`, `ButtonState` and `Axis` in `backend::input` now derive `Hash`.
- New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session. - New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session.
- The button code for a `PointerButtonEvent` may now be obtained using `PointerButtonEvent::button_code`. - The button code for a `PointerButtonEvent` may now be obtained using `PointerButtonEvent::button_code`.
- `Renderer` now allows texture filtering methods to be set.
### Bugfixes ### Bugfixes

View File

@ -16,7 +16,7 @@ use cgmath::{prelude::*, Matrix3, Vector2};
mod shaders; mod shaders;
mod version; mod version;
use super::{Bind, Frame, Renderer, Texture, Transform, Unbind}; use super::{Bind, Frame, Renderer, Texture, TextureFilter, Transform, Unbind};
use crate::backend::allocator::{ use crate::backend::allocator::{
dmabuf::{Dmabuf, WeakDmabuf}, dmabuf::{Dmabuf, WeakDmabuf},
Format, Format,
@ -420,6 +420,7 @@ impl Gles2Renderer {
/// - This renderer has no default framebuffer, use `Bind::bind` before rendering. /// - This renderer has no default framebuffer, use `Bind::bind` before rendering.
/// - Binding a new target, while another one is already bound, will replace the current target. /// - Binding a new target, while another one is already bound, will replace the current target.
/// - Shm buffers can be released after a successful import, without the texture handle becoming invalid. /// - Shm buffers can be released after a successful import, without the texture handle becoming invalid.
/// - Texture filtering starts with Nearest-downscaling and Linear-upscaling
pub unsafe fn new<L>(context: EGLContext, logger: L) -> Result<Gles2Renderer, Gles2Error> pub unsafe fn new<L>(context: EGLContext, logger: L) -> Result<Gles2Renderer, Gles2Error>
where where
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
@ -495,7 +496,7 @@ impl Gles2Renderer {
]; ];
let (tx, rx) = channel(); let (tx, rx) = channel();
let renderer = Gles2Renderer { let mut renderer = Gles2Renderer {
id: RENDERER_COUNTER.fetch_add(1, Ordering::SeqCst), id: RENDERER_COUNTER.fetch_add(1, Ordering::SeqCst),
gl, gl,
egl: context, egl: context,
@ -514,6 +515,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.upscale_filter(TextureFilter::Linear);
renderer.egl.unbind()?; renderer.egl.unbind()?;
Ok(renderer) Ok(renderer)
} }
@ -1007,6 +1010,28 @@ impl Renderer for Gles2Renderer {
type TextureId = Gles2Texture; type TextureId = Gles2Texture;
type Frame = Gles2Frame; type Frame = Gles2Frame;
fn downscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> {
self.make_current()?;
unsafe {
self.gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_MIN_FILTER, match filter {
TextureFilter::Nearest => ffi::NEAREST as i32,
TextureFilter::Linear => ffi::LINEAR as i32,
});
}
Ok(())
}
fn upscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error> {
self.make_current()?;
unsafe {
self.gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_MAG_FILTER, match filter {
TextureFilter::Nearest => ffi::NEAREST as i32,
TextureFilter::Linear => ffi::LINEAR as i32,
});
}
Ok(())
}
fn render<F, R>( fn render<F, R>(
&mut self, &mut self,
size: Size<i32, Physical>, size: Size<i32, Physical>,

View File

@ -53,6 +53,15 @@ pub enum Transform {
Flipped270, Flipped270,
} }
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
/// Texture filtering methods
pub enum TextureFilter {
/// Returns the value of the texture element that is nearest (in Manhattan distance) to the center of the pixel being textured.
Linear,
/// Returns the weighted average of the four texture elements that are closest to the center of the pixel being textured.
Nearest,
}
impl Transform { impl Transform {
/// A projection matrix to apply this transformation /// A projection matrix to apply this transformation
pub fn matrix(&self) -> Matrix3<f32> { pub fn matrix(&self) -> Matrix3<f32> {
@ -255,6 +264,11 @@ pub trait Renderer {
/// Type representing a currently in-progress frame during the [`Renderer::render`]-call /// Type representing a currently in-progress frame during the [`Renderer::render`]-call
type Frame: Frame<Error = Self::Error, TextureId = Self::TextureId>; type Frame: Frame<Error = Self::Error, TextureId = Self::TextureId>;
/// Set the filter method to be used when rendering a texture into a smaller area than its size
fn downscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error>;
/// Set the filter method to be used when rendering a texture into a larger area than its size
fn upscale_filter(&mut self, filter: TextureFilter) -> Result<(), Self::Error>;
/// Initialize a rendering context on the current rendering target with given dimensions and transformation. /// Initialize a rendering context on the current rendering target with given dimensions and transformation.
/// ///
/// This function *may* error, if: /// This function *may* error, if: