Add basic timer query support.

Inaccurate on macOS.
This commit is contained in:
Patrick Walton 2019-01-30 15:30:40 -08:00
parent e105bdb7c9
commit b6432fa47d
4 changed files with 121 additions and 5 deletions

26
Cargo.lock generated
View File

@ -169,6 +169,9 @@ dependencies = [
"pathfinder_svg 0.1.0", "pathfinder_svg 0.1.0",
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -321,6 +324,11 @@ dependencies = [
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itoa"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "jemalloc-sys" name = "jemalloc-sys"
version = "0.1.8" version = "0.1.8"
@ -798,6 +806,11 @@ dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ryu"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "safe-transmute" name = "safe-transmute"
version = "0.10.1" version = "0.10.1"
@ -867,6 +880,16 @@ dependencies = [
"syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "serde_json"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "simplecss" name = "simplecss"
version = "0.1.0" version = "0.1.0"
@ -1130,6 +1153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a" "checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a"
"checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d" "checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d"
"checksum inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84c683bde2d8413b8f1be3e459c30e4817672b6e7a31d9212b0323154e76eba7" "checksum inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84c683bde2d8413b8f1be3e459c30e4817672b6e7a31d9212b0323154e76eba7"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
"checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d" "checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d"
@ -1181,6 +1205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1" "checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
"checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3" "checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e" "checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
@ -1191,6 +1216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7" "checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7"
"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b" "checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b"
"checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e"
"checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e" "checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"

View File

@ -31,7 +31,7 @@ const DEBUG_FONT_VERTEX_SIZE: GLint = 8;
const DEBUG_SOLID_VERTEX_SIZE: GLint = 4; const DEBUG_SOLID_VERTEX_SIZE: GLint = 4;
const WINDOW_WIDTH: i16 = 400; const WINDOW_WIDTH: i16 = 400;
const WINDOW_HEIGHT: i16 = LINE_HEIGHT * 2 + PADDING + 3; const WINDOW_HEIGHT: i16 = LINE_HEIGHT * 3 + PADDING + 3;
const PADDING: i16 = 12; const PADDING: i16 = 12;
const FONT_ASCENT: i16 = 28; const FONT_ASCENT: i16 = 28;
const LINE_HEIGHT: i16 = 42; const LINE_HEIGHT: i16 = 42;
@ -112,7 +112,10 @@ impl DebugRenderer {
self.framebuffer_size = *window_size; self.framebuffer_size = *window_size;
} }
pub fn draw(&self, prepare_time: Duration, tile_time: Duration) { pub fn draw(&self,
prepare_time: Duration,
tile_time: Duration,
rendering_time: Option<Duration>) {
let window_rect = let window_rect =
Rect::new(Point2D::new(self.framebuffer_size.width as i16 - PADDING - WINDOW_WIDTH, Rect::new(Point2D::new(self.framebuffer_size.width as i16 - PADDING - WINDOW_WIDTH,
self.framebuffer_size.height as i16 - PADDING - WINDOW_HEIGHT), self.framebuffer_size.height as i16 - PADDING - WINDOW_HEIGHT),
@ -124,6 +127,12 @@ impl DebugRenderer {
self.draw_text(&format!("Tiling: {:.3} ms", duration_ms(tile_time)), self.draw_text(&format!("Tiling: {:.3} ms", duration_ms(tile_time)),
&Point2D::new(window_rect.origin.x + PADDING, &Point2D::new(window_rect.origin.x + PADDING,
window_rect.origin.y + PADDING + FONT_ASCENT + LINE_HEIGHT)); window_rect.origin.y + PADDING + FONT_ASCENT + LINE_HEIGHT));
if let Some(rendering_time) = rendering_time {
self.draw_text(&format!("Rendering: {:.3} ms", duration_ms(rendering_time)),
&Point2D::new(
window_rect.origin.x + PADDING,
window_rect.origin.y + PADDING + FONT_ASCENT + LINE_HEIGHT * 2));
}
} }
fn draw_solid_rect(&self, rect: &Rect<i16>, color: ColorU) { fn draw_solid_rect(&self, rect: &Rect<i16>, color: ColorU) {

View File

@ -373,3 +373,59 @@ impl Texture {
} }
} }
} }
pub struct TimerQuery {
gl_query: GLuint,
}
impl Drop for TimerQuery {
#[inline]
fn drop(&mut self) {
unsafe {
gl::DeleteQueries(1, &mut self.gl_query);
}
}
}
impl TimerQuery {
#[inline]
pub fn new() -> TimerQuery {
let mut query = TimerQuery { gl_query: 0 };
unsafe {
gl::GenQueries(1, &mut query.gl_query);
}
query
}
#[inline]
pub fn begin(&self) {
unsafe {
gl::BeginQuery(gl::TIME_ELAPSED, self.gl_query);
}
}
#[inline]
pub fn end(&self) {
unsafe {
gl::EndQuery(gl::TIME_ELAPSED);
}
}
#[inline]
pub fn is_available(&self) -> bool {
unsafe {
let mut result = 0;
gl::GetQueryObjectiv(self.gl_query, gl::QUERY_RESULT_AVAILABLE, &mut result);
result != gl::FALSE as GLint
}
}
#[inline]
pub fn get(&self) -> u64 {
unsafe {
let mut result = 0;
gl::GetQueryObjectui64v(self.gl_query, gl::QUERY_RESULT, &mut result);
result
}
}
}

View File

@ -13,7 +13,7 @@ extern crate serde_derive;
use crate::debug_text::DebugRenderer; use crate::debug_text::DebugRenderer;
use crate::device::{Buffer, BufferTarget, BufferUploadMode, Framebuffer, Program, Texture}; use crate::device::{Buffer, BufferTarget, BufferUploadMode, Framebuffer, Program, Texture};
use crate::device::{Uniform, VertexAttr}; use crate::device::{TimerQuery, Uniform, VertexAttr};
use clap::{App, Arg}; use clap::{App, Arg};
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Rect, Size2D};
use gl::types::{GLfloat, GLint, GLuint}; use gl::types::{GLfloat, GLint, GLuint};
@ -31,8 +31,9 @@ use rayon::ThreadPoolBuilder;
use sdl2::event::Event; use sdl2::event::Event;
use sdl2::keyboard::Keycode; use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile; use sdl2::video::GLProfile;
use std::collections::VecDeque;
use std::f32::consts::FRAC_PI_4; use std::f32::consts::FRAC_PI_4;
use std::time::Instant; use std::time::{Duration, Instant};
use std::path::PathBuf; use std::path::PathBuf;
use usvg::{Options as UsvgOptions, Tree}; use usvg::{Options as UsvgOptions, Tree};
@ -152,7 +153,8 @@ fn main() {
gl::Clear(gl::COLOR_BUFFER_BIT); gl::Clear(gl::COLOR_BUFFER_BIT);
renderer.render_scene(&built_scene); renderer.render_scene(&built_scene);
renderer.debug_renderer.draw(elapsed_prepare_time, elapsed_tile_time); let rendering_time = renderer.shift_timer_query();
renderer.debug_renderer.draw(elapsed_prepare_time, elapsed_tile_time, rendering_time);
} }
window.gl_swap_window(); window.gl_swap_window();
@ -311,6 +313,9 @@ struct Renderer {
mask_framebuffer: Framebuffer, mask_framebuffer: Framebuffer,
fill_colors_texture: Texture, fill_colors_texture: Texture,
pending_timer_queries: VecDeque<TimerQuery>,
free_timer_queries: Vec<TimerQuery>,
debug_renderer: DebugRenderer, debug_renderer: DebugRenderer,
main_framebuffer_size: Size2D<u32>, main_framebuffer_size: Size2D<u32>,
@ -355,6 +360,9 @@ impl Renderer {
mask_framebuffer, mask_framebuffer,
fill_colors_texture, fill_colors_texture,
pending_timer_queries: VecDeque::new(),
free_timer_queries: vec![],
debug_renderer, debug_renderer,
main_framebuffer_size: *main_framebuffer_size, main_framebuffer_size: *main_framebuffer_size,
@ -362,6 +370,9 @@ impl Renderer {
} }
fn render_scene(&mut self, built_scene: &BuiltScene) { fn render_scene(&mut self, built_scene: &BuiltScene) {
let timer_query = self.free_timer_queries.pop().unwrap_or_else(|| TimerQuery::new());
timer_query.begin();
self.upload_shaders(&built_scene.shaders); self.upload_shaders(&built_scene.shaders);
self.upload_solid_tiles(&built_scene.solid_tiles); self.upload_solid_tiles(&built_scene.solid_tiles);
@ -372,6 +383,20 @@ impl Renderer {
self.draw_batch_fills(batch); self.draw_batch_fills(batch);
self.draw_batch_mask_tiles(batch); self.draw_batch_mask_tiles(batch);
} }
timer_query.end();
self.pending_timer_queries.push_back(timer_query);
}
fn shift_timer_query(&mut self) -> Option<Duration> {
let query = self.pending_timer_queries.front()?;
if !query.is_available() {
return None
}
let query = self.pending_timer_queries.pop_front().unwrap();
let result = Duration::from_nanos(query.get());
self.free_timer_queries.push(query);
Some(result)
} }
fn upload_shaders(&mut self, shaders: &[ObjectShader]) { fn upload_shaders(&mut self, shaders: &[ObjectShader]) {