summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-05-01 18:25:29 +0200
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>2015-05-07 10:41:57 +0900
commit488b5e3ac3986d20cd6184668252cce70bb23760 (patch)
tree0616e2ae07a793c3152e5ee2da5e46188cf2b056
parentafb97c517d8041df61092b14e55c445a69cdfcff (diff)
downloadmpv-488b5e3ac3986d20cd6184668252cce70bb23760.tar.bz2
mpv-488b5e3ac3986d20cd6184668252cce70bb23760.tar.xz
cocoa: don't accidentally drop initial screen drawing
With --idle --force-window, or when started from the bundle, the cocoa code dropped the first frame. This resulted in a black frame on start sometimes. The reason was that the live resizing/redrawing code was invoked, which simply set skip_swap_buffer to false, blocking redrawing whatever was going to be rendered next. Normally this is done so that the following works: 1. vo_opengl draw a frame, releases GL lock 2. live resizing kicks in, redraw the frame 3. vo_opengl wants to call SwapBuffers, drawing a stale buffer overwritten by the live resizing code This is solved by setting skip_swap_buffer in 2., and querying it in 3. Fix this by resetting the skip_swap_buffer at a known good point: when vo_opengl starts drawing a new frame. The start_frame function returns bool, so that it can be merged with is_active in a following commit. (cherry picked from commit e23e4c7c603fc1cd911621d0f833031be4a6f7c7)
-rw-r--r--video/out/cocoa_common.h1
-rw-r--r--video/out/cocoa_common.m10
-rw-r--r--video/out/gl_cocoa.c6
-rw-r--r--video/out/gl_common.h5
-rw-r--r--video/out/vo_opengl.c6
5 files changed, 27 insertions, 1 deletions
diff --git a/video/out/cocoa_common.h b/video/out/cocoa_common.h
index 30792a674e..e2bed88d08 100644
--- a/video/out/cocoa_common.h
+++ b/video/out/cocoa_common.h
@@ -30,6 +30,7 @@ void vo_cocoa_uninit(struct vo *vo);
int vo_cocoa_config_window(struct vo *vo, uint32_t flags, void *gl_ctx);
void vo_cocoa_set_current_context(struct vo *vo, bool current);
+bool vo_cocoa_start_frame(struct vo *vo);
void vo_cocoa_swap_buffers(struct vo *vo);
int vo_cocoa_check_events(struct vo *vo);
int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg);
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index e768e06e7d..8a0473e729 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -632,13 +632,21 @@ static void draw_changes_after_next_frame(struct vo *vo)
}
}
+bool vo_cocoa_start_frame(struct vo *vo)
+{
+ struct vo_cocoa_state *s = vo->cocoa;
+
+ s->skip_swap_buffer = false;
+ return true;
+}
+
void vo_cocoa_swap_buffers(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
if (s->skip_swap_buffer && !s->waiting_frame) {
s->skip_swap_buffer = false;
- return;
+ s->pending_events |= VO_EVENT_EXPOSE;
} else {
[s->gl_ctx flushBuffer];
}
diff --git a/video/out/gl_cocoa.c b/video/out/gl_cocoa.c
index fd12ef4621..014bf38204 100644
--- a/video/out/gl_cocoa.c
+++ b/video/out/gl_cocoa.c
@@ -153,6 +153,11 @@ static void releaseGlContext_cocoa(MPGLContext *ctx)
CGLReleaseContext(p->ctx);
}
+static bool start_frame_cocoa(MPGLContext *ctx)
+{
+ return vo_cocoa_start_frame(ctx->vo);
+}
+
static void swapGlBuffers_cocoa(MPGLContext *ctx)
{
vo_cocoa_swap_buffers(ctx->vo);
@@ -169,6 +174,7 @@ void mpgl_set_backend_cocoa(MPGLContext *ctx)
ctx->config_window = config_window_cocoa;
ctx->releaseGlContext = releaseGlContext_cocoa;
ctx->swapGlBuffers = swapGlBuffers_cocoa;
+ ctx->start_frame = start_frame_cocoa;
ctx->vo_init = vo_cocoa_init;
ctx->register_resize_callback = vo_cocoa_register_resize_callback;
ctx->vo_uninit = vo_cocoa_uninit;
diff --git a/video/out/gl_common.h b/video/out/gl_common.h
index 8a133784c7..1c908cfa2b 100644
--- a/video/out/gl_common.h
+++ b/video/out/gl_common.h
@@ -118,6 +118,11 @@ typedef struct MPGLContext {
// If false, OpenGL renderers should not draw anything.
bool (*is_active)(struct MPGLContext *);
+ // Optional callback on the beginning of a frame. The frame will be finished
+ // with swapGlBuffers(). Like is_active, this returns false if use of the
+ // OpenGL context should be avoided.
+ bool (*start_frame)(struct MPGLContext *);
+
// For free use by the backend.
void *priv;
} MPGLContext;
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index e409eaa18d..43b2b9e04b 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -184,6 +184,12 @@ static void draw_image_timed(struct vo *vo, mp_image_t *mpi,
if (mpi)
gl_video_upload_image(p->renderer, mpi);
+
+ if (p->glctx->start_frame && !p->glctx->start_frame(p->glctx)) {
+ mpgl_unlock(p->glctx);
+ return;
+ }
+
gl_video_render_frame(p->renderer, 0, t);
// The playloop calls this last before waiting some time until it decides