-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opengl timers broken after f2298f3 #4721
Comments
The new method of querying timers is not supported on OS X. So this is expected behavior, unfortunately. (Going back to the old is not really easily possible due to the change in API and usage) |
Recently it feels like OSX supported in mpv actually decreases. Well, "feels" is the wrong word, it's not a feeling. |
The problem is OpenGL support on macOS, and their new API, Metal. Time for Vulkan, I guess.... |
No it's not because it used to work. |
Just googled that myself a few minutes ago. Seems like
https://lists.apple.com/archives/mac-opengl/2014/Nov/msg00005.html |
Well Apple just completely stopped caring about making sure OpenGL works on their platform. This is different from the past, before Metal existed. mpv has always been getting new features, it's just that the new features it's getting now break on OS X OpenGL because OS X OpenGL stopped getting updated.
GL_TIME_ELAPSED is not re-entrant, which is what caused e.g. the wrong measurements for stuff like OSD passes (which the new code solves). It's also further away from the vulkan API, which is part of the reason the API was changed. (
The problem is, there's no extension. It's technically supported, they just don't return any measurements. (Timestamp precision is 0) |
Hm I think Apple is complaining about how you can't discover timestamps overflow with GL_TIMESTAMP? Not sure if I follow. |
That's absolutely true, Apple last updated OpenGL on Os X with Mavericks 4 years ago, and then just stopped caring. And I think everyone agrees that advancement and new features can't be stopped because of one platform's shortcomings. |
Seems like every other platform compensates for this by actually reporting 64-bit results, which roll over once every 800 years.
This is irrelevant. They should be using wall clock time units, regardless of the GPU frequency. Sounds to me like they just don't care about doing it properly and would rather return nothing than return something broken (a decision I agree with, at least the second part). |
@miosenpai What drivers? |
I'm not at all competent with OGL so correct me if I'm wrong, but after @miosenpai report I checked ANGLE's repo and it seems to me that Google devs chose the same approach of Apple ones on this: google/angle@f04f667 |
This patch could fix it... diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c
index c7a714817a..f4eb0b9b7a 100644
--- a/video/out/opengl/common.c
+++ b/video/out/opengl/common.c
@@ -286,6 +286,7 @@ static const struct gl_functions gl_functions[] = {
DEF_FN(EndQuery),
DEF_FN(QueryCounter),
DEF_FN(IsQuery),
+ DEF_FN(GetQueryiv),
DEF_FN(GetQueryObjectiv),
DEF_FN(GetQueryObjecti64v),
DEF_FN(GetQueryObjectuiv),
@@ -628,6 +629,14 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
if (gl->DispatchCompute && gl->BindImageTexture)
gl->mpgl_caps |= MPGL_CAP_COMPUTE_SHADER;
+ // GL_ARB_timer_query & high precision timestamp queries
+ if (gl->QueryCounter) {
+ GLint bits;
+ gl->GetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &bits);
+ if (bits > 32)
+ gl->mpgl_caps |= MPGL_CAP_TIMESTAMP;
+ }
+
// Provided for simpler handling if no framebuffer support is available.
if (!gl->BindFramebuffer)
gl->BindFramebuffer = &dummy_glBindFramebuffer;
diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h
index 6d8015c8b3..2991cc0bce 100644
--- a/video/out/opengl/common.h
+++ b/video/out/opengl/common.h
@@ -57,6 +57,7 @@ enum {
MPGL_CAP_SSBO = (1 << 21), // GL_ARB_shader_storage_buffer_object
MPGL_CAP_COMPUTE_SHADER = (1 << 22), // GL_ARB_compute_shader & GL_ARB_shader_image_load_store
MPGL_CAP_NESTED_ARRAY = (1 << 23), // GL_ARB_arrays_of_arrays
+ MPGL_CAP_TIMESTAMP = (1 << 24), // GL_TIMESTAMP queries supported
MPGL_CAP_SW = (1 << 30), // indirect or sw renderer
};
@@ -208,6 +209,7 @@ struct GL {
void (GLAPIENTRY *EndQuery)(GLenum);
void (GLAPIENTRY *QueryCounter)(GLuint, GLenum);
GLboolean (GLAPIENTRY *IsQuery)(GLuint);
+ void (GLAPIENTRY *GetQueryiv)(GLenum, GLenum, GLint *);
void (GLAPIENTRY *GetQueryObjectiv)(GLuint, GLenum, GLint *);
void (GLAPIENTRY *GetQueryObjecti64v)(GLuint, GLenum, GLint64 *);
void (GLAPIENTRY *GetQueryObjectuiv)(GLuint, GLenum, GLuint *);
diff --git a/video/out/opengl/gl_headers.h b/video/out/opengl/gl_headers.h
index 9f479dd42f..f36bd47d17 100644
--- a/video/out/opengl/gl_headers.h
+++ b/video/out/opengl/gl_headers.h
@@ -65,6 +65,7 @@
#define GL_TIME_ELAPSED 0x88BF
#define GL_TIMESTAMP 0x8E28
+#define GL_QUERY_COUNTER_BITS 0x8864
// --- GL 4.3 or GL_ARB_debug_output
diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c
index 6509d9043a..9fcc2bed18 100644
--- a/video/out/opengl/ra_gl.c
+++ b/video/out/opengl/ra_gl.c
@@ -921,6 +921,7 @@ struct gl_timer {
GLuint stop[GL_QUERY_OBJECT_NUM];
int idx;
uint64_t result;
+ bool active;
};
static ra_timer *gl_timer_create(struct ra *ra)
@@ -952,29 +953,53 @@ static void gl_timer_destroy(struct ra *ra, ra_timer *ratimer)
static void gl_timer_start(struct ra *ra, ra_timer *ratimer)
{
- GL *gl = ra_gl_get(ra);
+ struct ra_gl *p = ra->priv;
+ GL *gl = p->gl;
struct gl_timer *timer = ratimer;
+ // GL_TIME_ELAPSED queries are not re-entrant, so just do nothing instead
+ // of crashing. Work-around for platforms that don't support GL_TIMESTAMP
+ if (p->timer_active)
+ return;
+
// 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;
+ if (gl->IsQuery(timer->stop[timer->idx])) {
+ gl->GetQueryObjectui64v(timer->stop[timer->idx], GL_QUERY_RESULT, &stop);
+ timer->result = stop - start;
+ } else {
+ timer->result = start;
+ }
}
- gl->QueryCounter(timer->start[timer->idx], GL_TIMESTAMP);
+ if (gl->mpgl_caps & MPGL_CAP_TIMESTAMP) {
+ gl->QueryCounter(timer->start[timer->idx], GL_TIMESTAMP);
+ } else {
+ gl->BeginQuery(GL_TIME_ELAPSED, timer->start[timer->idx]);
+ p->timer_active = timer->active = true;
+ }
}
static uint64_t gl_timer_stop(struct ra *ra, ra_timer *ratimer)
{
- GL *gl = ra_gl_get(ra);
+ struct ra_gl *p = ra->priv;
+ GL *gl = p->gl;
struct gl_timer *timer = ratimer;
- gl->QueryCounter(timer->stop[timer->idx++], GL_TIMESTAMP);
- timer->idx %= GL_QUERY_OBJECT_NUM;
+ if (p->timer_active && !timer->active)
+ return 0;
+
+ if (timer->active) {
+ gl->EndQuery(GL_TIME_ELAPSED);
+ p->timer_active = timer->active = false;
+ } else {
+ gl->QueryCounter(timer->stop[timer->idx], GL_TIMESTAMP);
+ }
+ timer->idx = (timer->idx + 1) % GL_QUERY_OBJECT_NUM;
return timer->result;
}
diff --git a/video/out/opengl/ra_gl.h b/video/out/opengl/ra_gl.h
index 08f0197433..334db69cfd 100644
--- a/video/out/opengl/ra_gl.h
+++ b/video/out/opengl/ra_gl.h
@@ -8,6 +8,7 @@
struct ra_gl {
GL *gl;
bool debug_enable;
+ bool timer_active; // hack for GL_TIME_ELAPSED
};
// For ra_tex.priv |
Seems like their rationale is different though - complaining about lack of timestamps reported by D3D11. (Ironically contradicting what apple seems to have suggested) |
I can confirm that the patch above works as expected on my machine. |
@haasn Yeah, that works, but it's missing a definition for GL_EXT_disjoint_timer_query: DEF_FN_NAME(GetQueryiv, "glGetQueryivEXT"), |
@quilloss Not necessarily, it could just be the case that uploading the frames actually spikes now. It could also be the case that GL_TIMESTAMP is more accurate then GL_TIME_ELAPSED, rather than the other way around. Hard to tell. |
I'll just revert it, since I can live with just using the global |
(Thanks. I absolutely realize it's a pain in the ass to work around broken operating systems you don't even use yourself. I appreciate every effort made to support/provide features to a larger set of systems) |
@Argon- Well, you're the one writing the stats script, which I love. Making it actually work on your system is the least I could do. :p |
mpv version and platform
git master
macOS 10.12.6
Reproduction steps
Open a video.
Expected behavior
Timers work.
Actual behavior
They're all stuck to 0. The culprit seems to be commit f2298f3, before that they work fine.
Log file
Log with
--msg-level=vo=debug
: https://0x0.st/dXC.txtThe text was updated successfully, but these errors were encountered: