int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h) { assert(ctx->renderer); gl_video_set_gl_state(ctx->renderer); pthread_mutex_lock(&ctx->lock); struct vo *vo = ctx->active; ctx->force_update |= ctx->reconfigured; ctx->frozen = false; if (ctx->vp_w != vp_w || ctx->vp_h != vp_h) ctx->force_update = true; if (ctx->force_update && vo) { ctx->force_update = false; ctx->vp_w = vp_w; ctx->vp_h = vp_h; struct mp_rect src, dst; struct mp_osd_res osd; mp_get_src_dst_rects(ctx->log, &ctx->vo_opts, vo->driver->caps, &ctx->img_params, vp_w, abs(vp_h), 1.0, &src, &dst, &osd); gl_video_resize(ctx->renderer, vp_w, vp_h, &src, &dst, &osd); } if (ctx->reconfigured) { gl_video_set_osd_source(ctx->renderer, vo ? vo->osd : NULL); gl_video_config(ctx->renderer, &ctx->img_params); } if (ctx->update_new_opts) { struct vo_priv *p = vo ? vo->priv : NULL; struct vo_priv *opts = ctx->new_opts ? ctx->new_opts : p; if (opts) { gl_video_set_options(ctx->renderer, opts->renderer_opts); gl_video_configure_queue(ctx->renderer, vo); ctx->gl->debug_context = opts->use_gl_debug; gl_video_set_debug(ctx->renderer, opts->use_gl_debug); frame_queue_shrink(ctx, opts->frame_queue_size); } } ctx->reconfigured = false; ctx->update_new_opts = false; struct mp_csp_equalizer *eq = gl_video_eq_ptr(ctx->renderer); if (ctx->eq_changed) { memcpy(eq->values, ctx->eq.values, sizeof(eq->values)); gl_video_eq_update(ctx->renderer); } ctx->eq_changed = false; ctx->eq = *eq; struct vo_frame *frame = frame_queue_pop(ctx); if (frame) { talloc_free(ctx->cur_frame); ctx->cur_frame = vo_frame_ref(frame); } else { frame = vo_frame_ref(ctx->cur_frame); } struct vo_frame dummy = {0}; if (!frame) frame = &dummy; if (ctx->approx_vsync > 0) { frame->prev_vsync = prev_sync(ctx, mp_time_us()); frame->next_vsync = frame->prev_vsync + ctx->approx_vsync; } pthread_mutex_unlock(&ctx->lock); gl_video_render_frame(ctx->renderer, frame, fbo); gl_video_unset_gl_state(ctx->renderer); if (frame != &dummy) talloc_free(frame); pthread_mutex_lock(&ctx->lock); const int left = ctx->queued_frames; if (vo && left > 0) update(vo->priv); pthread_mutex_unlock(&ctx->lock); return left; }
int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h) { assert(ctx->renderer); gl_video_set_gl_state(ctx->renderer); pthread_mutex_lock(&ctx->lock); struct vo *vo = ctx->active; ctx->force_update |= ctx->reconfigured; if (ctx->vp_w != vp_w || ctx->vp_h != vp_h) ctx->force_update = true; if (ctx->force_update && vo) { ctx->force_update = false; ctx->vp_w = vp_w; ctx->vp_h = vp_h; struct mp_rect src, dst; struct mp_osd_res osd; mp_get_src_dst_rects(ctx->log, &ctx->vo_opts, vo->driver->caps, &ctx->img_params, vp_w, abs(vp_h), 1.0, &src, &dst, &osd); gl_video_resize(ctx->renderer, vp_w, vp_h, &src, &dst, &osd); } if (ctx->reconfigured) { gl_video_set_osd_source(ctx->renderer, vo ? vo->osd : NULL); gl_video_config(ctx->renderer, &ctx->img_params); } if (ctx->update_new_opts) { struct vo_priv *p = vo ? vo->priv : NULL; struct vo_priv *opts = ctx->new_opts ? ctx->new_opts : p; if (opts) { int queue = 0; gl_video_set_options(ctx->renderer, opts->renderer_opts, &queue); ctx->vsync_timed = opts->renderer_opts->interpolation; if (ctx->vsync_timed) queue += 0.050 * 1e6; // disable video timing vo_set_flip_queue_params(vo, queue, false); ctx->gl->debug_context = opts->use_gl_debug; gl_video_set_debug(ctx->renderer, opts->use_gl_debug); frame_queue_shrink(ctx, opts->frame_queue_size); } } ctx->reconfigured = false; ctx->update_new_opts = false; struct mp_csp_equalizer *eq = gl_video_eq_ptr(ctx->renderer); if (ctx->eq_changed) { memcpy(eq->values, ctx->eq.values, sizeof(eq->values)); gl_video_eq_update(ctx->renderer); } ctx->eq_changed = false; ctx->eq = *eq; struct mp_image *mpi = frame_queue_pop(ctx); if (mpi) { struct frame_timing *t = mpi->priv; // set by draw_image_timed if (t) ctx->cur_pts = t->pts; } struct frame_timing timing = { .pts = ctx->cur_pts, }; if (ctx->approx_vsync > 0) { timing.prev_vsync = prev_sync(ctx, mp_time_us()); timing.next_vsync = timing.prev_vsync + ctx->approx_vsync; } pthread_mutex_unlock(&ctx->lock); if (mpi) gl_video_set_image(ctx->renderer, mpi); gl_video_render_frame(ctx->renderer, fbo, timing.pts ? &timing : NULL); gl_video_unset_gl_state(ctx->renderer); pthread_mutex_lock(&ctx->lock); const int left = ctx->queued_frames; if (vo && (left > 0 || ctx->vsync_timed)) update(vo->priv); pthread_mutex_unlock(&ctx->lock); return left; } int mpv_opengl_cb_report_flip(mpv_opengl_cb_context *ctx, int64_t time) { pthread_mutex_lock(&ctx->lock); int64_t next = time > 0 ? time : mp_time_us(); if (ctx->recent_flip) ctx->approx_vsync = next - ctx->recent_flip; ctx->recent_flip = next; pthread_mutex_unlock(&ctx->lock); return 0; }