summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-03-20 13:37:47 +0100
committerwm4 <wm4@nowhere>2017-03-20 13:37:47 +0100
commitb0cbda84ed923c8915642443b7cf5de5a2ba7b26 (patch)
treef55fce180487486f332dd73c6ffb9928187d4f2c
parent8fb9cc253457a58c39013906643e8dc92171adbe (diff)
downloadmpv-b0cbda84ed923c8915642443b7cf5de5a2ba7b26.tar.bz2
mpv-b0cbda84ed923c8915642443b7cf5de5a2ba7b26.tar.xz
vo_opengl: add a backend start_frame callback for context_vdpau
Might be useful for other backends too. For context_vdpau, resize handling, presentation, and handling the mapping state becomes somewhat less awkward.
-rw-r--r--video/out/opengl/context.c6
-rw-r--r--video/out/opengl/context.h6
-rw-r--r--video/out/opengl/context_vdpau.c78
-rw-r--r--video/out/vo_opengl.c2
4 files changed, 52 insertions, 40 deletions
diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c
index 4985c8a326..6fdc123fb6 100644
--- a/video/out/opengl/context.c
+++ b/video/out/opengl/context.c
@@ -240,6 +240,12 @@ int mpgl_control(struct MPGLContext *ctx, int *events, int request, void *arg)
return ctx->driver->control(ctx, events, request, arg);
}
+void mpgl_start_frame(struct MPGLContext *ctx)
+{
+ if (ctx->driver->start_frame)
+ ctx->driver->start_frame(ctx);
+}
+
void mpgl_swap_buffers(struct MPGLContext *ctx)
{
ctx->driver->swap_buffers(ctx);
diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h
index 7eabbd4886..229c5ef54f 100644
--- a/video/out/opengl/context.h
+++ b/video/out/opengl/context.h
@@ -59,6 +59,11 @@ struct mpgl_driver {
// Return 0 on success, negative value (-1) on error.
int (*reconfig)(struct MPGLContext *ctx);
+ // Called when rendering starts. The backend can map or resize the
+ // framebuffer, or update GL.main_fb. swap_buffers() ends the frame.
+ // Optional.
+ void (*start_frame)(struct MPGLContext *ctx);
+
// Present the frame.
void (*swap_buffers)(struct MPGLContext *ctx);
@@ -99,6 +104,7 @@ MPGLContext *mpgl_init(struct vo *vo, const char *backend_name, int vo_flags);
void mpgl_uninit(MPGLContext *ctx);
int mpgl_reconfig_window(struct MPGLContext *ctx);
int mpgl_control(struct MPGLContext *ctx, int *events, int request, void *arg);
+void mpgl_start_frame(struct MPGLContext *ctx);
void mpgl_swap_buffers(struct MPGLContext *ctx);
int mpgl_find_backend(const char *name);
diff --git a/video/out/opengl/context_vdpau.c b/video/out/opengl/context_vdpau.c
index 1d8479e9dc..4d5d2538e2 100644
--- a/video/out/opengl/context_vdpau.c
+++ b/video/out/opengl/context_vdpau.c
@@ -295,7 +295,8 @@ static int glx_init(struct MPGLContext *ctx, int flags)
p->num_surfaces = NUM_SURFACES;
for (int n = 0; n < p->num_surfaces; n++)
p->surfaces[n].surface = VDP_INVALID_HANDLE;
- p->current_surface = -1;
+
+ ctx->flip_v = true;
return 0;
@@ -304,30 +305,25 @@ uninit:
return -1;
}
-static void glx_next_framebuffer(struct MPGLContext *ctx)
+static int glx_reconfig(struct MPGLContext *ctx)
+{
+ vo_x11_config_vo_window(ctx->vo);
+ return 0;
+}
+
+static int glx_control(struct MPGLContext *ctx, int *events, int request,
+ void *arg)
+{
+ return vo_x11_control(ctx->vo, events, request, arg);
+}
+
+static void glx_start_frame(struct MPGLContext *ctx)
{
struct priv *p = ctx->priv;
struct vdp_functions *vdp = &p->vdp->vdp;
VdpStatus vdp_st;
GL *gl = ctx->gl;
- ctx->main_fb = 0;
-
- int current_surface = p->current_surface++;
- p->current_surface = p->current_surface % p->num_surfaces;
-
- if (current_surface >= 0) {
- struct surface *surface = &p->surfaces[current_surface];
-
- if (surface->mapped)
- ctx->gl->VDPAUUnmapSurfacesNV(1, &surface->registered);
- surface->mapped = false;
-
- vdp_st = vdp->presentation_queue_display(p->vdp_queue, surface->surface,
- 0, 0, 0);
- CHECK_VDP_WARNING(ctx, "trying to present vdp surface");
- }
-
struct surface *surface = &p->surfaces[p->current_surface];
if (surface->surface != VDP_INVALID_HANDLE) {
@@ -341,34 +337,35 @@ static void glx_next_framebuffer(struct MPGLContext *ctx)
if (surface->w != ctx->vo->dwidth || surface->h != ctx->vo->dheight)
recreate_vdpau_surface(ctx, surface);
- if (surface->surface == VDP_INVALID_HANDLE) {
- p->current_surface = -1;
- return;
- }
- gl->VDPAUMapSurfacesNV(1, &surface->registered);
- surface->mapped = true;
- ctx->main_fb = surface->fbo;
- ctx->flip_v = true;
+ ctx->main_fb = surface->fbo; // 0 if creating the surface failed
+
+ if (surface->surface != VDP_INVALID_HANDLE) {
+ gl->VDPAUMapSurfacesNV(1, &surface->registered);
+ surface->mapped = true;
+ }
}
-static int glx_reconfig(struct MPGLContext *ctx)
+static void glx_swap_buffers(struct MPGLContext *ctx)
{
- vo_x11_config_vo_window(ctx->vo);
+ struct priv *p = ctx->priv;
+ struct vdp_functions *vdp = &p->vdp->vdp;
+ VdpStatus vdp_st;
+ GL *gl = ctx->gl;
- glx_next_framebuffer(ctx); // map initial FBO
- return 0;
-}
+ struct surface *surface = &p->surfaces[p->current_surface];
+ if (surface->surface == VDP_INVALID_HANDLE)
+ return; // surface alloc probably failed before
-static int glx_control(struct MPGLContext *ctx, int *events, int request,
- void *arg)
-{
- return vo_x11_control(ctx->vo, events, request, arg);
-}
+ if (surface->mapped)
+ gl->VDPAUUnmapSurfacesNV(1, &surface->registered);
+ surface->mapped = false;
-static void glx_swap_buffers(struct MPGLContext *ctx)
-{
- glx_next_framebuffer(ctx);
+ vdp_st = vdp->presentation_queue_display(p->vdp_queue, surface->surface,
+ 0, 0, 0);
+ CHECK_VDP_WARNING(ctx, "trying to present vdp surface");
+
+ p->current_surface = (p->current_surface + 1) % p->num_surfaces;
}
static void glx_wakeup(struct MPGLContext *ctx)
@@ -386,6 +383,7 @@ const struct mpgl_driver mpgl_driver_vdpauglx = {
.priv_size = sizeof(struct priv),
.init = glx_init,
.reconfig = glx_reconfig,
+ .start_frame = glx_start_frame,
.swap_buffers = glx_swap_buffers,
.control = glx_control,
.wakeup = glx_wakeup,
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 88c23fae32..9b3f944e21 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -122,6 +122,8 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
struct gl_priv *p = vo->priv;
GL *gl = p->gl;
+ mpgl_start_frame(p->glctx);
+
if (gl->FenceSync && p->num_vsync_fences < p->opts.vsync_fences) {
GLsync fence = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);;
if (fence)