diff --git a/CHANGELOG.md b/CHANGELOG.md index 7feaa88..110b268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - `X11Surface` is now multi-window capable. - `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` +- `Gles2Renderer` now automatically flips the `render` result to account for OpenGLs coordinate system ### Additions diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index f5a63bc..a41c478 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -743,53 +743,19 @@ fn render_surface( // and draw to our buffer match renderer - .render( - mode.size, - Transform::Flipped180, // Scanout is rotated - |renderer, frame| { - render_layers_and_windows( - renderer, - frame, - window_map, - output_geometry, - output_scale, - logger, - )?; + .render(mode.size, Transform::Normal, |renderer, frame| { + render_layers_and_windows(renderer, frame, window_map, output_geometry, output_scale, logger)?; - // set cursor - if output_geometry.to_f64().contains(pointer_location) { - let (ptr_x, ptr_y) = pointer_location.into(); - let relative_ptr_location = - Point::::from((ptr_x as i32, ptr_y as i32)) - output_geometry.loc; - // draw the dnd icon if applicable - { - if let Some(ref wl_surface) = dnd_icon.as_ref() { - if wl_surface.as_ref().is_alive() { - 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( + // set cursor + if output_geometry.to_f64().contains(pointer_location) { + let (ptr_x, ptr_y) = pointer_location.into(); + let relative_ptr_location = + Point::::from((ptr_x as i32, ptr_y as i32)) - output_geometry.loc; + // draw the dnd icon if applicable + { + if let Some(ref wl_surface) = dnd_icon.as_ref() { + if wl_surface.as_ref().is_alive() { + draw_dnd_icon( renderer, frame, wl_surface, @@ -797,38 +763,61 @@ fn render_surface( 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(()) - }, - ) + // 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::::into) .and_then(|x| x) .map_err(Into::::into) diff --git a/anvil/src/x11.rs b/anvil/src/x11.rs index 04ec7d0..69766c8 100644 --- a/anvil/src/x11.rs +++ b/anvil/src/x11.rs @@ -239,56 +239,23 @@ pub fn run_x11(log: Logger) { // drawing logic match renderer - // X11 scanout for a Dmabuf is upside down // TODO: Address this issue in renderer. - .render( - backend_data.mode.size, - Transform::Flipped180, - |renderer, frame| { - render_layers_and_windows( - renderer, - frame, - &*window_map, - output_geometry, - output_scale, - &log, - )?; + .render(backend_data.mode.size, Transform::Normal, |renderer, frame| { + render_layers_and_windows( + renderer, + frame, + &*window_map, + output_geometry, + output_scale, + &log, + )?; - // draw the dnd icon if any - { - let guard = dnd_icon.lock().unwrap(); - if let Some(ref surface) = *guard { - if surface.as_ref().is_alive() { - 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( + // draw the dnd icon if any + { + let guard = dnd_icon.lock().unwrap(); + if let Some(ref surface) = *guard { + if surface.as_ref().is_alive() { + draw_dnd_icon( renderer, frame, surface, @@ -296,21 +263,49 @@ pub fn run_x11(log: Logger) { output_scale, &log, )?; - } else { - cursor_visible = true; } } + } - #[cfg(feature = "debug")] - { - use crate::drawing::draw_fps; + // 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; - 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::::into) .and_then(|x| x) .map_err(Into::::into) diff --git a/src/backend/renderer/gles2/mod.rs b/src/backend/renderer/gles2/mod.rs index 5c15b3a..762100b 100644 --- a/src/backend/renderer/gles2/mod.rs +++ b/src/backend/renderer/gles2/mod.rs @@ -1077,11 +1077,14 @@ impl Renderer for Gles2Renderer { renderer[2][0] = -(1.0f32.copysign(renderer[0][0] + renderer[1][0])); 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 { gl: self.gl.clone(), programs: self.programs.clone(), // output transformation passed in by the user - current_projection: transform.matrix() * renderer, + current_projection: flip180 * transform.matrix() * renderer, }; let result = rendering(self, &mut frame); diff --git a/src/backend/winit/mod.rs b/src/backend/winit/mod.rs index c534fed..63a7a3f 100644 --- a/src/backend/winit/mod.rs +++ b/src/backend/winit/mod.rs @@ -298,7 +298,8 @@ impl WinitGraphicsBackend { }; 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.renderer.unbind()?; Ok(result)