diff options
author | Niklas Haas <git@haasn.xyz> | 2017-08-05 18:20:45 +0200 |
---|---|---|
committer | Niklas Haas <git@haasn.xyz> | 2017-08-06 00:10:20 +0200 |
commit | f2298f394ec1688e9a02483b15902de24bda403e (patch) | |
tree | 9a0c4594a5edab8d8cb5c7f4a8d4d8d5f3aa8999 /video/out/opengl/ra_gl.c | |
parent | a680c643ebb124195fb30619a7e37246660fac7e (diff) | |
download | mpv-f2298f394ec1688e9a02483b15902de24bda403e.tar.bz2 mpv-f2298f394ec1688e9a02483b15902de24bda403e.tar.xz |
vo_opengl: move timers to struct ra
In order to prevent code duplication and keep the ra abstraction as
small as possible, `ra` only implements the actual timer queries,
it does not do pooling/averaging of the results. This is instead moved
to a ra-neutral struct timer_pool in utils.c.
Diffstat (limited to 'video/out/opengl/ra_gl.c')
-rw-r--r-- | video/out/opengl/ra_gl.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c index 4299dd0348..7b78f7d924 100644 --- a/video/out/opengl/ra_gl.c +++ b/video/out/opengl/ra_gl.c @@ -840,6 +840,75 @@ static void gl_renderpass_run(struct ra *ra, pass_gl->first_run = false; } +// Timers in GL use query objects, and are asynchronous. So pool a few of +// these together. GL_QUERY_OBJECT_NUM should be large enough to avoid this +// ever blocking. We can afford to throw query objects around, there's no +// practical limit on them and their overhead is small. + +#define GL_QUERY_OBJECT_NUM 8 + +struct gl_timer { + GLuint start[GL_QUERY_OBJECT_NUM]; + GLuint stop[GL_QUERY_OBJECT_NUM]; + int idx; + uint64_t result; +}; + +static ra_timer *gl_timer_create(struct ra *ra) +{ + GL *gl = ra_gl_get(ra); + + if (!gl->GenQueries) + return NULL; + + struct gl_timer *timer = talloc_zero(NULL, struct gl_timer); + gl->GenQueries(GL_QUERY_OBJECT_NUM, timer->start); + gl->GenQueries(GL_QUERY_OBJECT_NUM, timer->stop); + + return (ra_timer *)timer; +} + +static void gl_timer_destroy(struct ra *ra, ra_timer *ratimer) +{ + if (!ratimer) + return; + + GL *gl = ra_gl_get(ra); + struct gl_timer *timer = ratimer; + + gl->DeleteQueries(GL_QUERY_OBJECT_NUM, timer->start); + gl->DeleteQueries(GL_QUERY_OBJECT_NUM, timer->stop); + talloc_free(timer); +} + +static void gl_timer_start(struct ra *ra, ra_timer *ratimer) +{ + GL *gl = ra_gl_get(ra); + struct gl_timer *timer = ratimer; + + // If this query object already contains a result, we need to retrieve it + timer->result = 0; + if (gl->IsQuery(timer->start[timer->idx])) { + uint64_t start = 0, stop = 0; + gl->GetQueryObjectui64v(timer->start[timer->idx], GL_QUERY_RESULT, &start); + gl->GetQueryObjectui64v(timer->stop[timer->idx], GL_QUERY_RESULT, &stop); + timer->result = stop - start; + } + + gl->QueryCounter(timer->start[timer->idx], GL_TIMESTAMP); +} + +static uint64_t gl_timer_stop(struct ra *ra, ra_timer *ratimer) +{ + GL *gl = ra_gl_get(ra); + struct gl_timer *timer = ratimer; + + gl->QueryCounter(timer->stop[timer->idx++], GL_TIMESTAMP); + timer->idx %= GL_QUERY_OBJECT_NUM; + + return timer->result; +} + static struct ra_fns ra_fns_gl = { .destroy = gl_destroy, .tex_create = gl_tex_create, @@ -853,4 +922,8 @@ static struct ra_fns ra_fns_gl = { .renderpass_create = gl_renderpass_create, .renderpass_destroy = gl_renderpass_destroy, .renderpass_run = gl_renderpass_run, + .timer_create = gl_timer_create, + .timer_destroy = gl_timer_destroy, + .timer_start = gl_timer_start, + .timer_stop = gl_timer_stop, }; |