summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/video.c
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2016-06-05 21:55:30 +0200
committerwm4 <wm4@nowhere>2016-06-07 12:16:15 +0200
commit8ceb935bd8e1062ff83287c00cca0b7428a7dfba (patch)
tree0183f856b6262ae8b65d65bdf0caa466c03985f3 /video/out/opengl/video.c
parent88b584656d9752573cc4320c845a6d31b5877140 (diff)
downloadmpv-8ceb935bd8e1062ff83287c00cca0b7428a7dfba.tar.bz2
mpv-8ceb935bd8e1062ff83287c00cca0b7428a7dfba.tar.xz
vo_opengl: add time queries
To avoid blocking the CPU, we use 8 time objects and rotate through them, only blocking until the last possible moment (before we need access to them on the next iteration through the ring buffer). I tested it out on my machine and 4 query objects were enough to guarantee block-free querying, but the extra margin shouldn't hurt. Frame render times are just output at the end of each frame, via MP_DBG. This might be improved in the future. (In particular, I want to expose these numbers as properties so that users get some more visible feedback about render times) Currently, we measure pass_render_frame and pass_draw_to_screen separately because the former might be called multiple times due to interpolation. Doing it this way gives more faithful numbers. Same goes for frame upload times.
Diffstat (limited to 'video/out/opengl/video.c')
-rw-r--r--video/out/opengl/video.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 8a36f489b5..fe7c0abaa9 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -196,6 +196,10 @@ struct gl_video {
GLuint nnedi3_weights_buffer;
+ struct gl_timer *upload_timer;
+ struct gl_timer *render_timer;
+ struct gl_timer *present_timer;
+
struct mp_image_params real_image_params; // configured format
struct mp_image_params image_params; // texture format (mind hwdec case)
struct mp_imgfmt_desc image_desc;
@@ -2497,6 +2501,11 @@ static void pass_render_frame(struct gl_video *p)
if (p->dumb_mode)
return;
+ // start the render timer here. it will continue to the end of this
+ // function, to render the time needed to draw (excluding screen
+ // presentation)
+ gl_timer_start(p->render_timer);
+
p->use_linear = p->opts.linear_scaling || p->opts.sigmoid_upscaling;
pass_read_video(p);
pass_opt_hook_point(p, "NATIVE", &p->texture_offset);
@@ -2553,10 +2562,14 @@ static void pass_render_frame(struct gl_video *p)
}
pass_opt_hook_point(p, "SCALED", NULL);
+
+ gl_timer_stop(p->render_timer);
}
static void pass_draw_to_screen(struct gl_video *p, int fbo)
{
+ gl_timer_start(p->present_timer);
+
if (p->dumb_mode)
pass_render_frame_dumb(p, fbo);
@@ -2582,6 +2595,8 @@ static void pass_draw_to_screen(struct gl_video *p, int fbo)
pass_dither(p);
finish_pass_direct(p, fbo, p->vp_w, p->vp_h, &p->dst_rect);
+
+ gl_timer_stop(p->present_timer);
}
// Draws an interpolate frame to fbo, based on the frame timing in t
@@ -2754,6 +2769,16 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
p->frames_drawn += 1;
}
+static void timer_dbg(struct gl_video *p, const char *name, struct gl_timer *t)
+{
+ if (gl_timer_sample_count(t) > 0) {
+ MP_DBG(p, "%s time: last %dus avg %dus peak %dus\n", name,
+ (int)gl_timer_last_us(t),
+ (int)gl_timer_avg_us(t),
+ (int)gl_timer_peak_us(t));
+ }
+}
+
// (fbo==0 makes BindFramebuffer select the screen backbuffer)
void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo)
{
@@ -2857,6 +2882,11 @@ done:
gl->Flush();
p->frames_rendered++;
+
+ // Report performance metrics
+ timer_dbg(p, "upload", p->upload_timer);
+ timer_dbg(p, "render", p->render_timer);
+ timer_dbg(p, "present", p->present_timer);
}
// vp_w/vp_h is the implicit size of the target framebuffer.
@@ -2971,6 +3001,8 @@ static bool gl_video_upload_image(struct gl_video *p, struct mp_image *mpi)
assert(mpi->num_planes == p->plane_count);
+ gl_timer_start(p->upload_timer);
+
mp_image_t pbo_mpi = *mpi;
bool pbo = map_image(p, &pbo_mpi);
if (pbo) {
@@ -2998,6 +3030,8 @@ static bool gl_video_upload_image(struct gl_video *p, struct mp_image *mpi)
if (pbo)
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ gl_timer_stop(p->upload_timer);
+
return true;
error:
@@ -3227,6 +3261,10 @@ static void init_gl(struct gl_video *p)
gl->DeleteTextures(1, &tex);
}
+ p->upload_timer = gl_timer_create(p->gl);
+ p->render_timer = gl_timer_create(p->gl);
+ p->present_timer = gl_timer_create(p->gl);
+
debug_check_gl(p, "after init_gl");
}
@@ -3245,6 +3283,10 @@ void gl_video_uninit(struct gl_video *p)
gl->DeleteTextures(1, &p->lut_3d_texture);
+ gl_timer_free(p->upload_timer);
+ gl_timer_free(p->render_timer);
+ gl_timer_free(p->present_timer);
+
mpgl_osd_destroy(p->osd);
gl_set_debug_logger(gl, NULL);