summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-03-20 13:31:28 +0100
committerwm4 <wm4@nowhere>2017-03-20 13:31:28 +0100
commit8fb9cc253457a58c39013906643e8dc92171adbe (patch)
treecd78041d0ea61c580c628d15eb90d5ae2433b8b8 /video
parent03fe50651baeb506ca8b6fb2b597598a096be2f6 (diff)
downloadmpv-8fb9cc253457a58c39013906643e8dc92171adbe.tar.bz2
mpv-8fb9cc253457a58c39013906643e8dc92171adbe.tar.xz
vo_opengl: read framebuffer depth from actual FBO used for rendering
In some cases, such as when using the libmpv opengl-cb API, or with certain vo_opengl backends, the main framebuffer is never accessed. Instead, rendering is done to a FBO that acts as back buffer. This meant an incorrect/broken bit depth could be used for dithering. Change it to read the framebuffer depth lazily on the first render call. Also move the main FBO field out of the GL struct to MPGLContext, because the renderer's init function does not need to access it anymore.
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/common.h1
-rw-r--r--video/out/opengl/context.h3
-rw-r--r--video/out/opengl/context_dxinterop.c4
-rw-r--r--video/out/opengl/context_vdpau.c4
-rw-r--r--video/out/opengl/utils.c6
-rw-r--r--video/out/opengl/utils.h2
-rw-r--r--video/out/opengl/video.c20
-rw-r--r--video/out/vo_opengl.c6
8 files changed, 25 insertions, 21 deletions
diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h
index afb5b61f7e..e9bda4918b 100644
--- a/video/out/opengl/common.h
+++ b/video/out/opengl/common.h
@@ -94,7 +94,6 @@ struct GL {
char *extensions; // Equivalent to GL_EXTENSIONS
int mpgl_caps; // Bitfield of MPGL_CAP_* constants
bool debug_context; // use of e.g. GLX_CONTEXT_DEBUG_BIT_ARB
- GLuint main_fb; // framebuffer to render to (normally 0)
void (GLAPIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei);
void (GLAPIENTRY *Clear)(GLbitfield);
diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h
index 92b9da0432..7eabbd4886 100644
--- a/video/out/opengl/context.h
+++ b/video/out/opengl/context.h
@@ -88,6 +88,9 @@ typedef struct MPGLContext {
// Flip the rendered image vertically. This is useful for dxinterop.
bool flip_v;
+ // framebuffer to render to (normally 0)
+ GLuint main_fb;
+
// For free use by the mpgl_driver.
void *priv;
} MPGLContext;
diff --git a/video/out/opengl/context_dxinterop.c b/video/out/opengl/context_dxinterop.c
index e98b0d55ae..a23318a6a4 100644
--- a/video/out/opengl/context_dxinterop.c
+++ b/video/out/opengl/context_dxinterop.c
@@ -294,7 +294,7 @@ static int d3d_size_dependent_create(MPGLContext *ctx)
return -1;
}
- gl->BindFramebuffer(GL_FRAMEBUFFER, gl->main_fb);
+ gl->BindFramebuffer(GL_FRAMEBUFFER, ctx->main_fb);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, p->texture, 0);
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -506,7 +506,7 @@ static int dxinterop_init(struct MPGLContext *ctx, int flags)
goto fail;
// Create the shared framebuffer
- gl->GenFramebuffers(1, &gl->main_fb);
+ gl->GenFramebuffers(1, &ctx->main_fb);
current_ctx = ctx;
gl->SwapInterval = dxinterop_swap_interval;
diff --git a/video/out/opengl/context_vdpau.c b/video/out/opengl/context_vdpau.c
index 2d00cb4ba6..1d8479e9dc 100644
--- a/video/out/opengl/context_vdpau.c
+++ b/video/out/opengl/context_vdpau.c
@@ -311,7 +311,7 @@ static void glx_next_framebuffer(struct MPGLContext *ctx)
VdpStatus vdp_st;
GL *gl = ctx->gl;
- ctx->gl->main_fb = 0;
+ ctx->main_fb = 0;
int current_surface = p->current_surface++;
p->current_surface = p->current_surface % p->num_surfaces;
@@ -348,7 +348,7 @@ static void glx_next_framebuffer(struct MPGLContext *ctx)
gl->VDPAUMapSurfacesNV(1, &surface->registered);
surface->mapped = true;
- gl->main_fb = surface->fbo;
+ ctx->main_fb = surface->fbo;
ctx->flip_v = true;
}
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index 420df369f0..2ec8f43898 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -100,15 +100,15 @@ void gl_upload_tex(GL *gl, GLenum target, GLenum format, GLenum type,
gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
-mp_image_t *gl_read_window_contents(GL *gl, int w, int h)
+mp_image_t *gl_read_fbo_contents(GL *gl, int fbo, int w, int h)
{
if (gl->es)
return NULL; // ES can't read from front buffer
mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, w, h);
if (!image)
return NULL;
- gl->BindFramebuffer(GL_FRAMEBUFFER, gl->main_fb);
- GLenum obj = gl->main_fb ? GL_COLOR_ATTACHMENT0 : GL_FRONT;
+ gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
+ GLenum obj = fbo ? GL_COLOR_ATTACHMENT0 : GL_FRONT;
gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
gl->ReadBuffer(obj);
//flip image while reading (and also avoid stride-related trouble)
diff --git a/video/out/opengl/utils.h b/video/out/opengl/utils.h
index 069844caa6..9b57cb5296 100644
--- a/video/out/opengl/utils.h
+++ b/video/out/opengl/utils.h
@@ -30,7 +30,7 @@ void gl_upload_tex(GL *gl, GLenum target, GLenum format, GLenum type,
const void *dataptr, int stride,
int x, int y, int w, int h);
-mp_image_t *gl_read_window_contents(GL *gl, int w, int h);
+mp_image_t *gl_read_fbo_contents(GL *gl, int fbo, int w, int h);
const char* mp_sampler_type(GLenum texture_target);
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 6ad1db6b90..49b99e90b5 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -2643,6 +2643,17 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo)
return;
}
+ if (p->fb_depth == 0) {
+ debug_check_gl(p, "before retrieving framebuffer depth");
+ p->fb_depth = gl_get_fb_depth(gl, fbo);
+ debug_check_gl(p, "retrieving framebuffer depth");
+ if (p->fb_depth > 0) {
+ MP_VERBOSE(p, "Reported display depth: %d\n", p->fb_depth);
+ } else {
+ p->fb_depth = 8;
+ }
+ }
+
p->broken_frame = false;
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -3127,15 +3138,6 @@ static void init_gl(struct gl_video *p)
if (p->texture_16bit_depth > 0)
MP_VERBOSE(p, "16 bit texture depth: %d.\n", p->texture_16bit_depth);
- debug_check_gl(p, "before retrieving framebuffer depth");
- p->fb_depth = gl_get_fb_depth(gl, gl->main_fb);
- debug_check_gl(p, "retrieving framebuffer depth");
- if (p->fb_depth > 0) {
- MP_VERBOSE(p, "Reported display depth: %d\n", p->fb_depth);
- } else {
- p->fb_depth = 8;
- }
-
p->upload_timer = gl_timer_create(p->gl);
p->render_timer = gl_timer_create(p->gl);
p->present_timer = gl_timer_create(p->gl);
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index a1b9f6a75b..88c23fae32 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -128,7 +128,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
p->vsync_fences[p->num_vsync_fences++] = fence;
}
- gl_video_render_frame(p->renderer, frame, gl->main_fb);
+ gl_video_render_frame(p->renderer, frame, p->glctx->main_fb);
if (p->opts.use_glFinish)
gl->Finish();
@@ -270,8 +270,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
return VO_NOTIMPL;
}
case VOCTRL_SCREENSHOT_WIN: {
- struct mp_image *screen =
- gl_read_window_contents(p->gl, vo->dwidth, vo->dheight);
+ struct mp_image *screen = gl_read_fbo_contents(p->gl, p->glctx->main_fb,
+ vo->dwidth, vo->dheight);
if (!screen)
break; // redirect to backend
// set image parameters according to the display, if possible