vo_opengl: expose performance timers as properties

This is plumbed through a new VOCTRL, VOCTRL_PERFORMANCE_DATA, and
exposed as properties render-time-last, render-time-avg etc.

All of these numbers are in microseconds, which gives a good precision
range when just outputting them via show-text. (Lua scripts can
obviously still do their own formatting etc.)

Signed-off-by: wm4 <wm4@nowhere>
This commit is contained in:
Niklas Haas
2016-06-06 02:44:15 +02:00
committed by wm4
parent 8ceb935bd8
commit 393a069112
6 changed files with 101 additions and 0 deletions

View File

@@ -894,6 +894,30 @@ Property list
.. note:: This is only an estimate. (It's computed from two unreliable .. note:: This is only an estimate. (It's computed from two unreliable
quantities: fps and possibly rounded timestamps.) quantities: fps and possibly rounded timestamps.)
``render-time-last``
Time needed to render the last frame in microseconds. Not implemented by
all VOs.
``render-time-avg``
Average of ``render-time-last`` over the last few frames. (The exact
averaging time is variable, but it should generally be a few seconds)
``render-time-peak``
Peak (maximum) of ``render-time-last`` over the last few frames.
``present-time-last``, ``present-time-avg``, ``present-time-peak``
Analogous to ``render-time-last`` etc. but measures the time needed to
draw a rendered frame to the screen. Not implemented by all VOs.
(This is separate from ``render-time-last`` because VOs may interpolate,
deinterlace or otherwise mix multiple source frames into a single output
frame)
``upload-time-last``, ``upload-time-avg``, ``upload-time-peak``
Analogous to ``render-time-last`` etc. but measures the time needed to
upload a frame from system memory to a GPU texture. Not implemented by all
VOs.
``path`` ``path``
Full path of the currently played file. Usually this is exactly the same Full path of the currently played file. Usually this is exactly the same
string you pass on the mpv command line or the ``loadfile`` command, even string you pass on the mpv command line or the ``loadfile`` command, even

View File

@@ -2381,6 +2381,39 @@ static int panscan_property_helper(void *ctx, struct m_property *prop,
return r; return r;
} }
// Properties retrieved through VOCTRL_PERFORMANCE_DATA
static int perfdata_property_helper(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
if (!mpctx->video_out)
return M_PROPERTY_UNAVAILABLE;
struct voctrl_performance_data data = {0};
if (vo_control(mpctx->video_out, VOCTRL_PERFORMANCE_DATA, &data) <= 0)
return M_PROPERTY_UNAVAILABLE;
// Figure out the right field based on the name. This string
// match should never fail (based on the hard-coded property names)
struct bstr name = bstr0(prop->name), prefix, field;
bstr_split_tok(name, "-", &prefix, &name);
bstr_split_tok(name, "-", &name, &field);
// No need to have a failure case or fallthrough since these checks are all
// mutually exclusive and will never fail (based on the hard-coded names)
struct voctrl_performance_entry e = {0};
if (bstrcmp0(prefix, "upload") == 0) e = data.upload;
if (bstrcmp0(prefix, "render") == 0) e = data.render;
if (bstrcmp0(prefix, "present") == 0) e = data.present;
uint64_t val = 0;
if (bstrcmp0(field, "last") == 0) val = e.last;
if (bstrcmp0(field, "avg") == 0) val = e.avg;
if (bstrcmp0(field, "peak") == 0) val = e.peak;
return m_property_int64_ro(action, arg, val);
}
/// Helper to set vo flags. /// Helper to set vo flags.
/** \ingroup PropertyImplHelper /** \ingroup PropertyImplHelper
*/ */
@@ -3785,6 +3818,16 @@ static const struct m_property mp_properties[] = {
{"estimated-frame-count", mp_property_frame_count}, {"estimated-frame-count", mp_property_frame_count},
{"estimated-frame-number", mp_property_frame_number}, {"estimated-frame-number", mp_property_frame_number},
{"upload-time-last", perfdata_property_helper},
{"upload-time-avg", perfdata_property_helper},
{"upload-time-peak", perfdata_property_helper},
{"render-time-last", perfdata_property_helper},
{"render-time-avg", perfdata_property_helper},
{"render-time-peak", perfdata_property_helper},
{"present-time-last", perfdata_property_helper},
{"present-time-avg", perfdata_property_helper},
{"present-time-peak", perfdata_property_helper},
{"osd-width", mp_property_osd_w}, {"osd-width", mp_property_osd_w},
{"osd-height", mp_property_osd_h}, {"osd-height", mp_property_osd_h},
{"osd-par", mp_property_osd_par}, {"osd-par", mp_property_osd_par},

View File

@@ -2908,6 +2908,24 @@ void gl_video_resize(struct gl_video *p, int vp_w, int vp_h,
mpgl_osd_resize(p->osd, p->osd_rect, p->image_params.stereo_out); mpgl_osd_resize(p->osd, p->osd_rect, p->image_params.stereo_out);
} }
static struct voctrl_performance_entry gl_video_perfentry(struct gl_timer *t)
{
return (struct voctrl_performance_entry) {
.last = gl_timer_last_us(t),
.avg = gl_timer_avg_us(t),
.peak = gl_timer_peak_us(t),
};
}
struct voctrl_performance_data gl_video_perfdata(struct gl_video *p)
{
return (struct voctrl_performance_data) {
.upload = gl_video_perfentry(p->upload_timer),
.render = gl_video_perfentry(p->render_timer),
.present = gl_video_perfentry(p->present_timer),
};
}
static bool unmap_image(struct gl_video *p, struct mp_image *mpi) static bool unmap_image(struct gl_video *p, struct mp_image *mpi)
{ {
GL *gl = p->gl; GL *gl = p->gl;

View File

@@ -169,6 +169,7 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo);
void gl_video_resize(struct gl_video *p, int vp_w, int vp_h, void gl_video_resize(struct gl_video *p, int vp_w, int vp_h,
struct mp_rect *src, struct mp_rect *dst, struct mp_rect *src, struct mp_rect *dst,
struct mp_osd_res *osd); struct mp_osd_res *osd);
struct voctrl_performance_data gl_video_perfdata(struct gl_video *p);
struct mp_csp_equalizer; struct mp_csp_equalizer;
struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p); struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p);
void gl_video_eq_update(struct gl_video *p); void gl_video_eq_update(struct gl_video *p);

View File

@@ -77,6 +77,8 @@ enum mp_voctrl {
VOCTRL_UPDATE_WINDOW_TITLE, // char* VOCTRL_UPDATE_WINDOW_TITLE, // char*
VOCTRL_UPDATE_PLAYBACK_STATE, // struct voctrl_playback_state* VOCTRL_UPDATE_PLAYBACK_STATE, // struct voctrl_playback_state*
VOCTRL_PERFORMANCE_DATA, // struct voctrl_performance_data*
VOCTRL_SET_CURSOR_VISIBILITY, // bool* VOCTRL_SET_CURSOR_VISIBILITY, // bool*
VOCTRL_KILL_SCREENSAVER, VOCTRL_KILL_SCREENSAVER,
@@ -137,6 +139,16 @@ struct voctrl_playback_state {
int percent_pos; int percent_pos;
}; };
// VOCTRL_PERFORMANCE_DATA
struct voctrl_performance_entry {
// Times are in microseconds
uint64_t last, avg, peak;
};
struct voctrl_performance_data {
struct voctrl_performance_entry upload, render, present;
};
enum { enum {
// VO does handle mp_image_params.rotate in 90 degree steps // VO does handle mp_image_params.rotate in 90 degree steps
VO_CAP_ROTATE90 = 1 << 0, VO_CAP_ROTATE90 = 1 << 0,

View File

@@ -329,6 +329,9 @@ static int control(struct vo *vo, uint32_t request, void *data)
vo_wakeup(vo); vo_wakeup(vo);
} }
return true; return true;
case VOCTRL_PERFORMANCE_DATA:
*(struct voctrl_performance_data *)data = gl_video_perfdata(p->renderer);
return true;
} }
int events = 0; int events = 0;