Merge remote-tracking branch 'asajeffrey/demo-device-controls-viewports' into pf3

This commit is contained in:
Patrick Walton 2019-04-12 14:13:25 -07:00
commit e00e862df0
4 changed files with 105 additions and 58 deletions

View File

@ -15,8 +15,9 @@ 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;
use pathfinder_gpu::resources::ResourceLoader;
use std::cell::RefCell;
@ -48,6 +49,8 @@ pub unsafe extern "system" fn
height: i32) {
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));
@ -57,8 +60,7 @@ pub unsafe extern "system" fn
});
DEMO_APP.with(|demo_app| {
gl::load_with(|name| egl::get_proc_address(name) as *const c_void);
let options = Options::default();
*demo_app.borrow_mut() = Some(DemoApp::new(WindowImpl, window_size, options));
*demo_app.borrow_mut() = Some(DemoApp::new(window, window_size, options));
});
}
@ -156,7 +158,9 @@ pub unsafe extern "system" fn
EVENT_QUEUE.lock().unwrap().push(Event::OpenSVG(SVGPath::Resource(string)))
}
struct WindowImpl;
struct WindowImpl {
size: Point2DI32,
}
impl Window for WindowImpl {
fn gl_version(&self) -> GLVersion {
@ -167,6 +171,21 @@ impl Window for WindowImpl {
Point2DI32::new(0, 0)
}
fn viewport(&self, view: View) -> RectI32 {
let mut width = self.size.x();
let mut offset_x = 0;
let height = self.size.y();
if let View::Stereo(index) = view {
width = width / 2;
offset_x = (index as i32) * width;
}
let size = Point2DI32::new(width, height);
let offset = Point2DI32::new(offset_x, 0);
RectI32::new(offset, size)
}
fn make_current(&mut self, _view: View) {}
fn present(&mut self) {}
fn resource_loader(&self) -> &dyn ResourceLoader {

View File

@ -12,11 +12,11 @@
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
use crate::ui::{DemoUI, UIAction};
use crate::window::{CameraTransform, Event, 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};
use pathfinder_geometry::basic::rect::{RectF32, RectI32};
use pathfinder_geometry::basic::rect::RectF32;
use pathfinder_geometry::basic::transform2d::Transform2DF32;
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
use pathfinder_geometry::color::ColorU;
@ -117,8 +117,6 @@ impl<W> DemoApp<W> where W: Window {
options.command_line_overrides();
let view_box_size = view_box_size(options.mode, &window_size);
// 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 =
@ -203,7 +202,13 @@ impl<W> DemoApp<W> where W: Window {
self.current_frame = Some(Frame::new(transforms, ui_events));
// Begin drawing the scene.
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
for render_scene_index in 0..render_scene_count {
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));
}
render_scene_count
}
@ -255,8 +260,8 @@ impl<W> DemoApp<W> where W: Window {
}
Event::WindowResized(new_size) => {
self.window_size = new_size;
let view_box_size = view_box_size(self.ui.mode, &self.window_size);
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;
}
@ -354,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 = view_box_size(self.ui.mode, &self.window_size);
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
@ -382,8 +387,12 @@ impl<W> DemoApp<W> where W: Window {
}
pub fn draw_scene(&mut self, render_scene_index: u32) {
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(render_scene_index);
self.render_vector_scene();
if let Some(rendering_time) = self.renderer.shift_timer_query() {
self.current_frame.as_mut().unwrap().scene_rendering_times.push(rendering_time)
@ -398,9 +407,6 @@ impl<W> DemoApp<W> where W: Window {
let mut frame = self.current_frame.take().unwrap();
let drawable_size = self.window_size.device_size();
self.renderer.set_viewport(RectI32::new(Point2DI32::default(), drawable_size));
if self.pending_screenshot_path.is_some() {
self.take_screenshot();
}
@ -415,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 {
@ -444,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 = view_box_size(self.ui.mode, &self.window_size);
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 {
@ -541,7 +550,7 @@ impl<W> DemoApp<W> where W: Window {
});
}
fn render_vector_scene(&mut self, viewport_index: u32) {
fn render_vector_scene(&mut self) {
let built_scene = match self.scene_thread_proxy.receiver.recv().unwrap() {
SceneToMainMsg::BeginRenderScene(built_scene) => built_scene,
_ => panic!("Expected `BeginRenderScene`!"),
@ -549,11 +558,6 @@ impl<W> DemoApp<W> where W: Window {
self.current_frame.as_mut().unwrap().scene_stats.push(built_scene.stats());
let view_box_size = view_box_size(self.ui.mode, &self.window_size);
let viewport_origin_x = viewport_index as i32 * view_box_size.x();
let viewport = RectI32::new(Point2DI32::new(viewport_origin_x, 0), view_box_size);
self.renderer.set_viewport(viewport);
match self.monochrome_scene_color {
None => self.renderer.set_render_mode(RenderMode::Multicolor),
Some(fg_color) => {
@ -915,9 +919,13 @@ pub enum Mode {
}
impl Mode {
fn viewport_count(self) -> usize {
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)]
@ -959,27 +967,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();
@ -997,10 +1005,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,
}
}
}
@ -1082,14 +1090,6 @@ fn emit_message<W>(ui: &mut DemoUI<GLDevice>,
});
}
fn view_box_size(mode: Mode, window_size: &WindowSize) -> Point2DI32 {
let window_drawable_size = window_size.device_size();
match mode {
Mode::TwoD | Mode::ThreeD => window_drawable_size,
Mode::VR => Point2DI32::new(window_drawable_size.x() / 2, window_drawable_size.y()),
}
}
struct Frame {
transforms: Vec<RenderTransform>,
ui_events: Vec<UIEvent>,

View File

@ -12,9 +12,9 @@
use gl::types::GLuint;
use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
use pathfinder_geometry::distortion::BarrelDistortionCoefficients;
use pathfinder_geometry::basic::transform3d::Perspective;
use pathfinder_geometry::basic::transform3d::Transform3DF32;
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::ResourceLoader;
use rayon::ThreadPoolBuilder;
@ -24,6 +24,8 @@ pub trait Window {
fn gl_version(&self) -> GLVersion;
fn gl_default_framebuffer(&self) -> GLuint { 0 }
fn mouse_position(&self) -> Point2DI32;
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;
@ -76,6 +78,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
@ -90,4 +98,4 @@ pub enum SVGPath {
Default,
Resource(String),
Path(PathBuf),
}
}

View File

@ -14,8 +14,9 @@ use jemallocator;
use nfd::Response;
use pathfinder_demo::DemoApp;
use pathfinder_demo::Options;
use pathfinder_demo::window::{Event, Keycode, 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;
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
@ -81,6 +82,25 @@ impl Window for WindowImpl {
Point2DI32::new(mouse_state.x(), mouse_state.y())
}
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);
}
RectI32::new (
Point2DI32::new(x_offset, 0),
Point2DI32::new(width, height),
)
}
fn make_current(&mut self, _view: View) {
self.window.gl_make_current(&self.gl_context).unwrap();
}
fn present(&mut self) {
self.window.gl_swap_window();
}