summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/opengl/utils.c26
-rw-r--r--video/out/opengl/utils.h3
-rw-r--r--video/out/opengl/video.c6
-rw-r--r--video/out/vo_rpi.c3
4 files changed, 30 insertions, 8 deletions
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index 0bebe1263c..fa1131e815 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -481,6 +481,9 @@ struct gl_shader_cache {
struct sc_uniform *uniforms;
int num_uniforms;
+ // For checking that the user is calling gl_sc_reset() properly.
+ bool needs_reset;
+
bool error_state; // true if an error occurred
// temporary buffers (avoids frequent reallocations)
@@ -494,17 +497,26 @@ struct gl_shader_cache *gl_sc_create(GL *gl, struct mp_log *log)
.gl = gl,
.log = log,
};
+ gl_sc_reset(sc);
return sc;
}
+// Reset the previous pass. This must be called after
+// Unbind all GL state managed by sc - the current program and texture units.
void gl_sc_reset(struct gl_shader_cache *sc)
{
+ GL *gl = sc->gl;
+
+ if (sc->needs_reset)
+ gl->UseProgram(0);
+
sc->prelude_text.len = 0;
sc->header_text.len = 0;
sc->text.len = 0;
for (int n = 0; n < sc->num_uniforms; n++)
talloc_free(sc->uniforms[n].name);
sc->num_uniforms = 0;
+ sc->needs_reset = false;
}
static void sc_flush_cache(struct gl_shader_cache *sc)
@@ -867,14 +879,20 @@ static GLuint create_program(struct gl_shader_cache *sc, const char *vertex,
// 1. Generate vertex and fragment shaders from the fragment shader text added
// with gl_sc_add(). The generated shader program is cached (based on the
// text), so actual compilation happens only the first time.
-// 2. Update the uniforms set with gl_sc_uniform_*.
+// 2. Update the uniforms and textures set with gl_sc_uniform_*.
// 3. Make the new shader program current (glUseProgram()).
-// 4. Reset the sc state and prepare for a new shader program. (All uniforms
+// After that, you render, and then you call gc_sc_reset(), which does:
+// 1. Unbind the program and all textures.
+// 2. Reset the sc state and prepare for a new shader program. (All uniforms
// and fragment operations needed for the next program have to be re-added.)
-void gl_sc_gen_shader_and_reset(struct gl_shader_cache *sc)
+void gl_sc_generate(struct gl_shader_cache *sc)
{
GL *gl = sc->gl;
+ // gl_sc_reset() must be called after ending the previous render process,
+ // and before starting a new one.
+ assert(!sc->needs_reset);
+
assert(sc->vao);
for (int n = 0; n < MP_ARRAY_SIZE(sc->tmp); n++)
@@ -997,7 +1015,7 @@ void gl_sc_gen_shader_and_reset(struct gl_shader_cache *sc)
for (int n = 0; n < sc->num_uniforms; n++)
update_uniform(gl, entry, &sc->uniforms[n], n);
- gl_sc_reset(sc);
+ sc->needs_reset = true;
}
// Maximum number of simultaneous query objects to keep around. Reducing this
diff --git a/video/out/opengl/utils.h b/video/out/opengl/utils.h
index d81599a71f..ab3c13c915 100644
--- a/video/out/opengl/utils.h
+++ b/video/out/opengl/utils.h
@@ -167,8 +167,9 @@ void gl_sc_uniform_mat3(struct gl_shader_cache *sc, char *name,
bool transpose, GLfloat *v);
void gl_sc_set_vao(struct gl_shader_cache *sc, struct gl_vao *vao);
void gl_sc_enable_extension(struct gl_shader_cache *sc, char *name);
-void gl_sc_gen_shader_and_reset(struct gl_shader_cache *sc);
+void gl_sc_generate(struct gl_shader_cache *sc);
void gl_sc_reset(struct gl_shader_cache *sc);
+void gl_sc_unbind(struct gl_shader_cache *sc);
struct gl_timer;
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 040dbb2f3d..b000b2e7ce 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -1026,10 +1026,11 @@ static void finish_pass_direct(struct gl_video *p, GLint fbo, int vp_w, int vp_h
{
GL *gl = p->gl;
pass_prepare_src_tex(p);
+ gl_sc_generate(p->sc);
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
- gl_sc_gen_shader_and_reset(p->sc);
render_pass_quad(p, vp_w, vp_h, dst);
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_sc_reset(p->sc);
memset(&p->pass_tex, 0, sizeof(p->pass_tex));
p->pass_tex_num = 0;
}
@@ -2335,8 +2336,9 @@ static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts,
pass_colormanage(p, csp_srgb, true);
}
gl_sc_set_vao(p->sc, mpgl_osd_get_vao(p->osd));
- gl_sc_gen_shader_and_reset(p->sc);
+ gl_sc_generate(p->sc);
mpgl_osd_draw_part(p->osd, vp_w, vp_h, n);
+ gl_sc_reset(p->sc);
}
gl_sc_set_vao(p->sc, &p->vao);
}
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
index c046928f38..acec865c6b 100644
--- a/video/out/vo_rpi.c
+++ b/video/out/vo_rpi.c
@@ -285,8 +285,9 @@ static void update_osd(struct vo *vo)
abort();
}
gl_sc_set_vao(p->sc, mpgl_osd_get_vao(p->osd));
- gl_sc_gen_shader_and_reset(p->sc);
+ gl_sc_generate(p->sc);
mpgl_osd_draw_part(p->osd, p->osd_res.w, -p->osd_res.h, n);
+ gl_sc_reset(p->sc);
}
MP_STATS(vo, "stop rpi_osd");