renderer: Account for OpenGLs coordinate system in the Gles2Renderer

This commit is contained in:
Victor Brekenfeld 2021-11-27 21:48:01 +01:00
parent eccdd5221c
commit 76787fb7df
5 changed files with 122 additions and 133 deletions

View File

@ -33,6 +33,7 @@
- `X11Surface` is now multi-window capable. - `X11Surface` is now multi-window capable.
- `Renderer::clear` now expects a second argument to optionally only clear parts of the buffer/surface - `Renderer::clear` now expects a second argument to optionally only clear parts of the buffer/surface
- `Transform::transform_size` now takes a `Size` instead of two `u32` - `Transform::transform_size` now takes a `Size` instead of two `u32`
- `Gles2Renderer` now automatically flips the `render` result to account for OpenGLs coordinate system
### Additions ### Additions

View File

@ -743,53 +743,19 @@ fn render_surface(
// and draw to our buffer // and draw to our buffer
match renderer match renderer
.render( .render(mode.size, Transform::Normal, |renderer, frame| {
mode.size, render_layers_and_windows(renderer, frame, window_map, output_geometry, output_scale, logger)?;
Transform::Flipped180, // Scanout is rotated
|renderer, frame| {
render_layers_and_windows(
renderer,
frame,
window_map,
output_geometry,
output_scale,
logger,
)?;
// set cursor // set cursor
if output_geometry.to_f64().contains(pointer_location) { if output_geometry.to_f64().contains(pointer_location) {
let (ptr_x, ptr_y) = pointer_location.into(); let (ptr_x, ptr_y) = pointer_location.into();
let relative_ptr_location = let relative_ptr_location =
Point::<i32, Logical>::from((ptr_x as i32, ptr_y as i32)) - output_geometry.loc; Point::<i32, Logical>::from((ptr_x as i32, ptr_y as i32)) - output_geometry.loc;
// draw the dnd icon if applicable // draw the dnd icon if applicable
{ {
if let Some(ref wl_surface) = dnd_icon.as_ref() { if let Some(ref wl_surface) = dnd_icon.as_ref() {
if wl_surface.as_ref().is_alive() { if wl_surface.as_ref().is_alive() {
draw_dnd_icon( draw_dnd_icon(
renderer,
frame,
wl_surface,
relative_ptr_location,
output_scale,
logger,
)?;
}
}
}
// draw the cursor as relevant
{
// reset the cursor if the surface is no longer alive
let mut reset = false;
if let CursorImageStatus::Image(ref surface) = *cursor_status {
reset = !surface.as_ref().is_alive();
}
if reset {
*cursor_status = CursorImageStatus::Default;
}
if let CursorImageStatus::Image(ref wl_surface) = *cursor_status {
draw_cursor(
renderer, renderer,
frame, frame,
wl_surface, wl_surface,
@ -797,38 +763,61 @@ fn render_surface(
output_scale, output_scale,
logger, logger,
)?; )?;
} else {
frame.render_texture_at(
pointer_image,
relative_ptr_location
.to_f64()
.to_physical(output_scale as f64)
.to_i32_round(),
1,
output_scale as f64,
Transform::Normal,
1.0,
)?;
} }
} }
#[cfg(feature = "debug")]
{
draw_fps(
renderer,
frame,
fps_texture,
output_scale as f64,
surface.fps.avg().round() as u32,
)?;
surface.fps.tick();
}
} }
Ok(()) // draw the cursor as relevant
}, {
) // reset the cursor if the surface is no longer alive
let mut reset = false;
if let CursorImageStatus::Image(ref surface) = *cursor_status {
reset = !surface.as_ref().is_alive();
}
if reset {
*cursor_status = CursorImageStatus::Default;
}
if let CursorImageStatus::Image(ref wl_surface) = *cursor_status {
draw_cursor(
renderer,
frame,
wl_surface,
relative_ptr_location,
output_scale,
logger,
)?;
} else {
frame.render_texture_at(
pointer_image,
relative_ptr_location
.to_f64()
.to_physical(output_scale as f64)
.to_i32_round(),
1,
output_scale as f64,
Transform::Normal,
1.0,
)?;
}
}
#[cfg(feature = "debug")]
{
draw_fps(
renderer,
frame,
fps_texture,
output_scale as f64,
surface.fps.avg().round() as u32,
)?;
surface.fps.tick();
}
}
Ok(())
})
.map_err(Into::<SwapBuffersError>::into) .map_err(Into::<SwapBuffersError>::into)
.and_then(|x| x) .and_then(|x| x)
.map_err(Into::<SwapBuffersError>::into) .map_err(Into::<SwapBuffersError>::into)

View File

@ -239,56 +239,23 @@ pub fn run_x11(log: Logger) {
// drawing logic // drawing logic
match renderer match renderer
// X11 scanout for a Dmabuf is upside down
// TODO: Address this issue in renderer. // TODO: Address this issue in renderer.
.render( .render(backend_data.mode.size, Transform::Normal, |renderer, frame| {
backend_data.mode.size, render_layers_and_windows(
Transform::Flipped180, renderer,
|renderer, frame| { frame,
render_layers_and_windows( &*window_map,
renderer, output_geometry,
frame, output_scale,
&*window_map, &log,
output_geometry, )?;
output_scale,
&log,
)?;
// draw the dnd icon if any // draw the dnd icon if any
{ {
let guard = dnd_icon.lock().unwrap(); let guard = dnd_icon.lock().unwrap();
if let Some(ref surface) = *guard { if let Some(ref surface) = *guard {
if surface.as_ref().is_alive() { if surface.as_ref().is_alive() {
draw_dnd_icon( draw_dnd_icon(
renderer,
frame,
surface,
(x as i32, y as i32).into(),
output_scale,
&log,
)?;
}
}
}
// draw the cursor as relevant
{
let mut guard = cursor_status.lock().unwrap();
// reset the cursor if the surface is no longer alive
let mut reset = false;
if let CursorImageStatus::Image(ref surface) = *guard {
reset = !surface.as_ref().is_alive();
}
if reset {
*guard = CursorImageStatus::Default;
}
// draw as relevant
if let CursorImageStatus::Image(ref surface) = *guard {
cursor_visible = false;
draw_cursor(
renderer, renderer,
frame, frame,
surface, surface,
@ -296,21 +263,49 @@ pub fn run_x11(log: Logger) {
output_scale, output_scale,
&log, &log,
)?; )?;
} else {
cursor_visible = true;
} }
} }
}
#[cfg(feature = "debug")] // draw the cursor as relevant
{ {
use crate::drawing::draw_fps; let mut guard = cursor_status.lock().unwrap();
// reset the cursor if the surface is no longer alive
let mut reset = false;
draw_fps(renderer, frame, fps_texture, output_scale as f64, fps)?; if let CursorImageStatus::Image(ref surface) = *guard {
reset = !surface.as_ref().is_alive();
} }
Ok(()) if reset {
}, *guard = CursorImageStatus::Default;
) }
// draw as relevant
if let CursorImageStatus::Image(ref surface) = *guard {
cursor_visible = false;
draw_cursor(
renderer,
frame,
surface,
(x as i32, y as i32).into(),
output_scale,
&log,
)?;
} else {
cursor_visible = true;
}
}
#[cfg(feature = "debug")]
{
use crate::drawing::draw_fps;
draw_fps(renderer, frame, fps_texture, output_scale as f64, fps)?;
}
Ok(())
})
.map_err(Into::<SwapBuffersError>::into) .map_err(Into::<SwapBuffersError>::into)
.and_then(|x| x) .and_then(|x| x)
.map_err(Into::<SwapBuffersError>::into) .map_err(Into::<SwapBuffersError>::into)

View File

@ -1077,11 +1077,14 @@ impl Renderer for Gles2Renderer {
renderer[2][0] = -(1.0f32.copysign(renderer[0][0] + renderer[1][0])); renderer[2][0] = -(1.0f32.copysign(renderer[0][0] + renderer[1][0]));
renderer[2][1] = -(1.0f32.copysign(renderer[0][1] + renderer[1][1])); renderer[2][1] = -(1.0f32.copysign(renderer[0][1] + renderer[1][1]));
// We account for OpenGLs coordinate system here
let flip180 = Matrix3::new(1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0);
let mut frame = Gles2Frame { let mut frame = Gles2Frame {
gl: self.gl.clone(), gl: self.gl.clone(),
programs: self.programs.clone(), programs: self.programs.clone(),
// output transformation passed in by the user // output transformation passed in by the user
current_projection: transform.matrix() * renderer, current_projection: flip180 * transform.matrix() * renderer,
}; };
let result = rendering(self, &mut frame); let result = rendering(self, &mut frame);

View File

@ -298,7 +298,8 @@ impl WinitGraphicsBackend {
}; };
self.renderer.bind(self.egl.clone())?; self.renderer.bind(self.egl.clone())?;
let result = self.renderer.render(size, Transform::Normal, rendering)?; // Why is winit falling out of place with the coordinate system?
let result = self.renderer.render(size, Transform::Flipped180, rendering)?;
self.egl.swap_buffers()?; self.egl.swap_buffers()?;
self.renderer.unbind()?; self.renderer.unbind()?;
Ok(result) Ok(result)