Separated viewport from make_current.

This commit is contained in:
Alan Jeffrey 2019-04-12 11:30:00 -05:00
parent b98336a430
commit eedb8bbadf
4 changed files with 82 additions and 81 deletions

View File

@ -15,7 +15,7 @@ use jni::{JNIEnv, JavaVM};
use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JString, JValue}; use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JString, JValue};
use pathfinder_demo::DemoApp; use pathfinder_demo::DemoApp;
use pathfinder_demo::Options; use pathfinder_demo::Options;
use pathfinder_demo::window::{Event, SVGPath, Window, WindowSize}; use pathfinder_demo::window::{Event, SVGPath, View, Window, WindowSize};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gl::GLVersion; use pathfinder_gl::GLVersion;
@ -50,6 +50,7 @@ pub unsafe extern "system" fn
let logical_size = Point2DI32::new(width, height); let logical_size = Point2DI32::new(width, height);
let window_size = WindowSize { logical_size, backing_scale_factor: 1.0 }; let window_size = WindowSize { logical_size, backing_scale_factor: 1.0 };
let window = WindowImpl { size: logical_size }; let window = WindowImpl { size: logical_size };
let options = Options::default();
JAVA_ACTIVITY.with(|java_activity| { JAVA_ACTIVITY.with(|java_activity| {
*java_activity.borrow_mut() = Some(JavaActivity::new(env.clone(), activity)); *java_activity.borrow_mut() = Some(JavaActivity::new(env.clone(), activity));
@ -170,20 +171,11 @@ impl Window for WindowImpl {
Point2DI32::new(0, 0) Point2DI32::new(0, 0)
} }
fn view_box_size(&self, mode: Mode) -> Point2DI32 { fn viewport(&self, view: View) -> RectI32 {
let mut width = self.size.x();
let height = self.size.y();
if let Mode::VR = mode {
width = width / 2;
}
Point2DI32::new(width as i32, height as i32)
}
fn make_current(&mut self, mode: Mode, index: Option<u32>) -> RectI32 {
let mut width = self.size.x(); let mut width = self.size.x();
let mut offset_x = 0; let mut offset_x = 0;
let height = self.size.y(); let height = self.size.y();
if let (Mode::VR, Some(index)) = (mode, index) { if let View::Stereo(index) = view {
width = width / 2; width = width / 2;
offset_x = (index as i32) * width; offset_x = (index as i32) * width;
} }
@ -192,6 +184,8 @@ impl Window for WindowImpl {
RectI32::new(offset, size) RectI32::new(offset, size)
} }
fn make_current(&mut self, _view: View) {}
fn present(&mut self) {} fn present(&mut self) {}
fn resource_loader(&self) -> &dyn ResourceLoader { fn resource_loader(&self) -> &dyn ResourceLoader {

View File

@ -12,7 +12,7 @@
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray}; use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
use crate::ui::{BackgroundColor, DemoUI, UIAction}; use crate::ui::{BackgroundColor, DemoUI, UIAction};
use crate::window::{CameraTransform, Event, Mode, Keycode, SVGPath, Window, WindowSize}; use crate::window::{CameraTransform, Event, Keycode, SVGPath, View, Window, WindowSize};
use clap::{App, Arg}; use clap::{App, Arg};
use image::ColorType; use image::ColorType;
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32}; use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
@ -117,8 +117,6 @@ impl<W> DemoApp<W> where W: Window {
options.command_line_overrides(); options.command_line_overrides();
let view_box_size = window.view_box_size(options.mode);
// Set up Rayon. // Set up Rayon.
let mut thread_pool_builder = ThreadPoolBuilder::new(); let mut thread_pool_builder = ThreadPoolBuilder::new();
thread_pool_builder = options.adjust_thread_pool_settings(thread_pool_builder); thread_pool_builder = options.adjust_thread_pool_settings(thread_pool_builder);
@ -130,14 +128,15 @@ impl<W> DemoApp<W> where W: Window {
let scene_view_box = built_svg.scene.view_box; let scene_view_box = built_svg.scene.view_box;
let monochrome_scene_color = built_svg.scene.monochrome_color(); let monochrome_scene_color = built_svg.scene.monochrome_color();
let viewport = window.viewport(options.mode.view(0));
let renderer = Renderer::new(device, let renderer = Renderer::new(device,
resources, resources,
RectI32::new(Point2DI32::default(), view_box_size), viewport,
window_size.device_size()); window_size.device_size());
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
scene_thread_proxy.set_drawable_size(view_box_size); scene_thread_proxy.set_drawable_size(viewport.size());
let camera = Camera::new(options.mode, scene_view_box, view_box_size); let camera = Camera::new(options.mode, scene_view_box, viewport.size());
let ground_program = GroundProgram::new(&renderer.device, resources); let ground_program = GroundProgram::new(&renderer.device, resources);
let ground_solid_vertex_array = let ground_solid_vertex_array =
@ -204,7 +203,10 @@ impl<W> DemoApp<W> where W: Window {
// Begin drawing the scene. // Begin drawing the scene.
for render_scene_index in 0..render_scene_count { for render_scene_index in 0..render_scene_count {
self.window.make_current(self.ui.mode, Some(render_scene_index)); let view = self.ui.mode.view(render_scene_index);
let viewport = self.window.viewport(view);
self.window.make_current(view);
self.renderer.set_viewport(viewport);
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0)); self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
} }
@ -258,8 +260,8 @@ impl<W> DemoApp<W> where W: Window {
} }
Event::WindowResized(new_size) => { Event::WindowResized(new_size) => {
self.window_size = new_size; self.window_size = new_size;
let view_box_size = self.window.view_box_size(self.ui.mode); let viewport = self.window.viewport(self.ui.mode.view(0));
self.scene_thread_proxy.set_drawable_size(view_box_size); self.scene_thread_proxy.set_drawable_size(viewport.size());
self.renderer.set_main_framebuffer_size(self.window_size.device_size()); self.renderer.set_main_framebuffer_size(self.window_size.device_size());
self.dirty = true; self.dirty = true;
} }
@ -357,11 +359,11 @@ impl<W> DemoApp<W> where W: Window {
let built_svg = load_scene(self.window.resource_loader(), svg_path); let built_svg = load_scene(self.window.resource_loader(), svg_path);
self.ui.message = get_svg_building_message(&built_svg); self.ui.message = get_svg_building_message(&built_svg);
let view_box_size = self.window.view_box_size(self.ui.mode); let viewport_size = self.window.viewport(self.ui.mode.view(0)).size();
self.scene_view_box = built_svg.scene.view_box; self.scene_view_box = built_svg.scene.view_box;
self.monochrome_scene_color = built_svg.scene.monochrome_color(); self.monochrome_scene_color = built_svg.scene.monochrome_color();
self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size); self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size);
self.scene_thread_proxy.load_scene(built_svg.scene, view_box_size); self.scene_thread_proxy.load_scene(built_svg.scene, viewport_size);
self.dirty = true; self.dirty = true;
} }
Event::User { message_type: event_id, message_data: expected_epoch } if Event::User { message_type: event_id, message_data: expected_epoch } if
@ -385,7 +387,9 @@ impl<W> DemoApp<W> where W: Window {
} }
pub fn draw_scene(&mut self, render_scene_index: u32) { pub fn draw_scene(&mut self, render_scene_index: u32) {
let viewport = self.window.make_current(self.ui.mode, Some(render_scene_index)); let view = self.ui.mode.view(render_scene_index);
let viewport = self.window.viewport(view);
self.window.make_current(view);
self.renderer.set_viewport(viewport); self.renderer.set_viewport(viewport);
self.draw_environment(render_scene_index); self.draw_environment(render_scene_index);
self.render_vector_scene(); self.render_vector_scene();
@ -403,9 +407,6 @@ impl<W> DemoApp<W> where W: Window {
let mut frame = self.current_frame.take().unwrap(); let mut frame = self.current_frame.take().unwrap();
let viewport = self.window.make_current(self.ui.mode, None);
self.renderer.set_viewport(viewport);
if self.pending_screenshot_path.is_some() { if self.pending_screenshot_path.is_some() {
self.take_screenshot(); self.take_screenshot();
} }
@ -420,10 +421,13 @@ impl<W> DemoApp<W> where W: Window {
Some(frame.scene_rendering_times.iter().fold(zero, |sum, item| sum + *item)) Some(frame.scene_rendering_times.iter().fold(zero, |sum, item| sum + *item))
}; };
self.renderer.debug_ui.add_sample(aggregate_stats, tile_time, total_rendering_time); self.renderer.debug_ui.add_sample(aggregate_stats, tile_time, total_rendering_time);
}
if self.options.ui != UIVisibility::None { if self.options.ui != UIVisibility::None {
self.renderer.draw_debug_ui(); let viewport = self.window.viewport(View::Mono);
} self.window.make_current(View::Mono);
self.renderer.set_viewport(viewport);
self.renderer.draw_debug_ui();
} }
for ui_event in &frame.ui_events { for ui_event in &frame.ui_events {
@ -449,8 +453,8 @@ impl<W> DemoApp<W> where W: Window {
// //
// FIXME(pcwalton): This should really be an MVC setup. // FIXME(pcwalton): This should really be an MVC setup.
if self.camera.mode() != self.ui.mode { if self.camera.mode() != self.ui.mode {
let view_box_size = self.window.view_box_size(self.ui.mode); let viewport_size = self.window.viewport(self.ui.mode.view(0)).size();
self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size); self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size);
} }
for ui_event in frame.ui_events { for ui_event in frame.ui_events {
@ -903,6 +907,23 @@ impl Options {
} }
} }
#[derive(Clone, Copy, PartialEq)]
pub enum Mode {
TwoD = 0,
ThreeD = 1,
VR = 2,
}
impl Mode {
pub fn viewport_count(self) -> usize {
match self { Mode::TwoD | Mode::ThreeD => 1, Mode::VR => 2 }
}
pub fn view(self, viewport: u32) -> View {
match self { Mode::TwoD | Mode::ThreeD => View::Mono, Mode::VR => View::Stereo(viewport) }
}
}
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
pub enum UIVisibility { pub enum UIVisibility {
None, None,
@ -942,27 +963,27 @@ enum Camera {
} }
impl Camera { impl Camera {
fn new(mode: Mode, view_box: RectF32, view_box_size: Point2DI32) -> Camera { fn new(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera {
if mode == Mode::TwoD { if mode == Mode::TwoD {
Camera::new_2d(view_box, view_box_size) Camera::new_2d(view_box, viewport_size)
} else { } else {
Camera::new_3d(mode, view_box, view_box_size) Camera::new_3d(mode, view_box, viewport_size)
} }
} }
fn new_2d(view_box: RectF32, view_box_size: Point2DI32) -> Camera { fn new_2d(view_box: RectF32, viewport_size: Point2DI32) -> Camera {
let scale = i32::min(view_box_size.x(), view_box_size.y()) as f32 * let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 *
scale_factor_for_view_box(view_box); scale_factor_for_view_box(view_box);
let origin = view_box_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5); let origin = viewport_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5);
Camera::TwoD(Transform2DF32::from_scale(&Point2DF32::splat(scale)).post_translate(origin)) Camera::TwoD(Transform2DF32::from_scale(&Point2DF32::splat(scale)).post_translate(origin))
} }
fn new_3d(mode: Mode, view_box: RectF32, view_box_size: Point2DI32) -> Camera { fn new_3d(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera {
let viewport_count = mode.viewport_count(); let viewport_count = mode.viewport_count();
let aspect = view_box_size.x() as f32 / view_box_size.y() as f32; let aspect = viewport_size.x() as f32 / viewport_size.y() as f32;
let projection = Transform3DF32::from_perspective(FRAC_PI_4, aspect, NEAR_CLIP_PLANE, FAR_CLIP_PLANE); let projection = Transform3DF32::from_perspective(FRAC_PI_4, aspect, NEAR_CLIP_PLANE, FAR_CLIP_PLANE);
let transform = CameraTransform { let transform = CameraTransform {
perspective: Perspective::new(&projection, view_box_size), perspective: Perspective::new(&projection, viewport_size),
view: Transform3DF32::default(), view: Transform3DF32::default(),
}; };
let transforms = iter::repeat(transform).take(viewport_count).collect(); let transforms = iter::repeat(transform).take(viewport_count).collect();
@ -980,10 +1001,10 @@ impl Camera {
fn mode(&self) -> Mode { fn mode(&self) -> Mode {
match *self { match *self {
Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR, Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR,
Camera::ThreeD { .. } => Mode::ThreeD, Camera::ThreeD { .. } => Mode::ThreeD,
Camera::TwoD { .. } => Mode::TwoD, Camera::TwoD { .. } => Mode::TwoD,
} }
} }
} }

View File

@ -25,8 +25,8 @@ pub trait Window {
fn gl_version(&self) -> GLVersion; fn gl_version(&self) -> GLVersion;
fn gl_default_framebuffer(&self) -> GLuint { 0 } fn gl_default_framebuffer(&self) -> GLuint { 0 }
fn mouse_position(&self) -> Point2DI32; fn mouse_position(&self) -> Point2DI32;
fn view_box_size(&self, mode: Mode) -> Point2DI32; fn viewport(&self, view: View) -> RectI32;
fn make_current(&mut self, mode: Mode, index: Option<u32>) -> RectI32; fn make_current(&mut self, view: View);
fn present(&mut self); fn present(&mut self);
fn resource_loader(&self) -> &dyn ResourceLoader; fn resource_loader(&self) -> &dyn ResourceLoader;
fn create_user_event_id(&self) -> u32; fn create_user_event_id(&self) -> u32;
@ -79,6 +79,12 @@ impl WindowSize {
} }
} }
#[derive(Clone, Copy, Debug)]
pub enum View {
Mono,
Stereo(u32),
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CameraTransform { pub struct CameraTransform {
// The perspective which converts from camera coordinates to display coordinates // The perspective which converts from camera coordinates to display coordinates
@ -94,16 +100,3 @@ pub enum SVGPath {
Resource(String), Resource(String),
Path(PathBuf), Path(PathBuf),
} }
#[derive(Clone, Copy, PartialEq)]
pub enum Mode {
TwoD = 0,
ThreeD = 1,
VR = 2,
}
impl Mode {
pub fn viewport_count(self) -> usize {
match self { Mode::TwoD | Mode::ThreeD => 1, Mode::VR => 2 }
}
}

View File

@ -14,7 +14,7 @@ use jemallocator;
use nfd::Response; use nfd::Response;
use pathfinder_demo::DemoApp; use pathfinder_demo::DemoApp;
use pathfinder_demo::Options; use pathfinder_demo::Options;
use pathfinder_demo::window::{Event, Keycode, Mode, SVGPath, Window, WindowSize}; use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gl::GLVersion; use pathfinder_gl::GLVersion;
@ -82,30 +82,23 @@ impl Window for WindowImpl {
Point2DI32::new(mouse_state.x(), mouse_state.y()) Point2DI32::new(mouse_state.x(), mouse_state.y())
} }
fn view_box_size(&self, mode: Mode) -> Point2DI32 { fn viewport(&self, view: View) -> RectI32 {
let (mut width, height) = self.window.drawable_size(); let (width, height) = self.window.drawable_size();
if let Mode::VR = mode { let mut width = width as i32;
let height = height as i32;
let mut x_offset = 0;
if let View::Stereo(index) = view {
width = width / 2; width = width / 2;
x_offset = width * (index as i32);
} }
Point2DI32::new(width as i32, height as i32) RectI32::new (
Point2DI32::new(x_offset, 0),
Point2DI32::new(width, height),
)
} }
fn make_current(&mut self, mode: Mode, index: Option<u32>) -> RectI32 { fn make_current(&mut self, _view: View) {
let (width, height) = self.window.drawable_size();
let mut width = width as i32;
let height = height as i32;
let mut offset_x = 0;
if let (Mode::VR, Some(index)) = (mode, index) {
width = width / 2;
offset_x = (index as i32) * width;
}
let size = Point2DI32::new(width, height);
let offset = Point2DI32::new(offset_x, 0);
self.window.gl_make_current(&self.gl_context).unwrap(); self.window.gl_make_current(&self.gl_context).unwrap();
unsafe { gl::Viewport(offset_x, 0, width, height); }
RectI32::new(offset, size)
} }
fn present(&mut self) { fn present(&mut self) {