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

View File

@ -12,7 +12,7 @@
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
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 image::ColorType;
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
@ -117,8 +117,6 @@ impl<W> DemoApp<W> where W: Window {
options.command_line_overrides();
let view_box_size = window.view_box_size(options.mode);
// Set up Rayon.
let mut thread_pool_builder = ThreadPoolBuilder::new();
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 monochrome_scene_color = built_svg.scene.monochrome_color();
let viewport = window.viewport(options.mode.view(0));
let renderer = Renderer::new(device,
resources,
RectI32::new(Point2DI32::default(), view_box_size),
viewport,
window_size.device_size());
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_solid_vertex_array =
@ -204,7 +203,10 @@ impl<W> DemoApp<W> where W: Window {
// Begin drawing the scene.
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));
}
@ -258,8 +260,8 @@ impl<W> DemoApp<W> where W: Window {
}
Event::WindowResized(new_size) => {
self.window_size = new_size;
let view_box_size = self.window.view_box_size(self.ui.mode);
self.scene_thread_proxy.set_drawable_size(view_box_size);
let viewport = self.window.viewport(self.ui.mode.view(0));
self.scene_thread_proxy.set_drawable_size(viewport.size());
self.renderer.set_main_framebuffer_size(self.window_size.device_size());
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);
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.monochrome_scene_color = built_svg.scene.monochrome_color();
self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size);
self.scene_thread_proxy.load_scene(built_svg.scene, 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, viewport_size);
self.dirty = true;
}
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) {
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.draw_environment(render_scene_index);
self.render_vector_scene();
@ -403,9 +407,6 @@ impl<W> DemoApp<W> where W: Window {
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() {
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))
};
self.renderer.debug_ui.add_sample(aggregate_stats, tile_time, total_rendering_time);
}
if self.options.ui != UIVisibility::None {
self.renderer.draw_debug_ui();
}
if self.options.ui != UIVisibility::None {
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 {
@ -449,8 +453,8 @@ impl<W> DemoApp<W> where W: Window {
//
// FIXME(pcwalton): This should really be an MVC setup.
if self.camera.mode() != self.ui.mode {
let view_box_size = self.window.view_box_size(self.ui.mode);
self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size);
let viewport_size = self.window.viewport(self.ui.mode.view(0)).size();
self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size);
}
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)]
pub enum UIVisibility {
None,
@ -942,27 +963,27 @@ enum 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 {
Camera::new_2d(view_box, view_box_size)
Camera::new_2d(view_box, viewport_size)
} 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 {
let scale = i32::min(view_box_size.x(), view_box_size.y()) as f32 *
fn new_2d(view_box: RectF32, viewport_size: Point2DI32) -> Camera {
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 *
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))
}
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 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 transform = CameraTransform {
perspective: Perspective::new(&projection, view_box_size),
perspective: Perspective::new(&projection, viewport_size),
view: Transform3DF32::default(),
};
let transforms = iter::repeat(transform).take(viewport_count).collect();
@ -980,10 +1001,10 @@ impl Camera {
fn mode(&self) -> Mode {
match *self {
Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR,
Camera::ThreeD { .. } => Mode::ThreeD,
Camera::TwoD { .. } => Mode::TwoD,
}
Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR,
Camera::ThreeD { .. } => Mode::ThreeD,
Camera::TwoD { .. } => Mode::TwoD,
}
}
}

View File

@ -25,8 +25,8 @@ pub trait Window {
fn gl_version(&self) -> GLVersion;
fn gl_default_framebuffer(&self) -> GLuint { 0 }
fn mouse_position(&self) -> Point2DI32;
fn view_box_size(&self, mode: Mode) -> Point2DI32;
fn make_current(&mut self, mode: Mode, index: Option<u32>) -> RectI32;
fn viewport(&self, view: View) -> RectI32;
fn make_current(&mut self, view: View);
fn present(&mut self);
fn resource_loader(&self) -> &dyn ResourceLoader;
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)]
pub struct CameraTransform {
// The perspective which converts from camera coordinates to display coordinates
@ -94,16 +100,3 @@ pub enum SVGPath {
Resource(String),
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 pathfinder_demo::DemoApp;
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::rect::RectI32;
use pathfinder_gl::GLVersion;
@ -82,30 +82,23 @@ impl Window for WindowImpl {
Point2DI32::new(mouse_state.x(), mouse_state.y())
}
fn view_box_size(&self, mode: Mode) -> Point2DI32 {
let (mut width, height) = self.window.drawable_size();
if let Mode::VR = mode {
fn viewport(&self, view: View) -> RectI32 {
let (width, height) = self.window.drawable_size();
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;
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 {
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);
fn make_current(&mut self, _view: View) {
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) {