From 7b1e73139f73f446a472782e1465040c0e6b16dd Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 8 Feb 2018 01:55:31 +0100 Subject: vo_gpu: add internal ability to skip osd/subs for rendering Needed for the following commit. --- video/out/gpu/video.c | 44 ++++++++++++++++++++++++++++++-------------- video/out/gpu/video.h | 8 +++++++- video/out/vo_gpu.c | 2 +- video/out/vo_opengl_cb.c | 2 +- video/out/vo_rpi.c | 2 +- 5 files changed, 40 insertions(+), 18 deletions(-) (limited to 'video') diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index ea19fb1809..dcacdb1d01 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -2616,6 +2616,9 @@ static void pass_dither(struct gl_video *p) static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts, struct mp_osd_res rect, struct ra_fbo fbo, bool cms) { + if ((draw_flags & OSD_DRAW_SUB_ONLY) && (draw_flags & OSD_DRAW_OSD_ONLY)) + return; + mpgl_osd_generate(p->osd, rect, pts, p->image_params.stereo_out, draw_flags); timer_pool_start(p->osd_timer); @@ -2685,7 +2688,9 @@ static void pass_render_frame_dumb(struct gl_video *p) // The main rendering function, takes care of everything up to and including // upscaling. p->image is rendered. -static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, uint64_t id) +// flags: bit set of RENDER_FRAME_* flags +static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, + uint64_t id, int flags) { // initialize the texture parameters and temporary variables p->texture_w = p->image_params.w; @@ -2716,7 +2721,9 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, uint64_t if (vpts == MP_NOPTS_VALUE) vpts = p->osd_pts; - if (p->osd && p->opts.blend_subs == BLEND_SUBS_VIDEO) { + if (p->osd && p->opts.blend_subs == BLEND_SUBS_VIDEO && + (flags & RENDER_FRAME_SUBS)) + { double scale[2]; get_scale_factors(p, false, scale); struct mp_osd_res rect = { @@ -2735,7 +2742,9 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, uint64_t int vp_w = p->dst_rect.x1 - p->dst_rect.x0, vp_h = p->dst_rect.y1 - p->dst_rect.y0; - if (p->osd && p->opts.blend_subs == BLEND_SUBS_YES) { + if (p->osd && p->opts.blend_subs == BLEND_SUBS_YES && + (flags & RENDER_FRAME_SUBS)) + { // Recreate the real video size from the src/dst rects struct mp_osd_res rect = { .w = vp_w, .h = vp_h, @@ -2815,14 +2824,15 @@ static void pass_draw_to_screen(struct gl_video *p, struct ra_fbo fbo) finish_pass_fbo(p, fbo, false, &p->dst_rect); } +// flags: bit set of RENDER_FRAME_* flags static bool update_surface(struct gl_video *p, struct mp_image *mpi, - uint64_t id, struct surface *surf) + uint64_t id, struct surface *surf, int flags) { int vp_w = p->dst_rect.x1 - p->dst_rect.x0, vp_h = p->dst_rect.y1 - p->dst_rect.y0; pass_info_reset(p, false); - if (!pass_render_frame(p, mpi, id)) + if (!pass_render_frame(p, mpi, id, flags)) return false; // Frame blending should always be done in linear light to preserve the @@ -2840,8 +2850,9 @@ static bool update_surface(struct gl_video *p, struct mp_image *mpi, } // Draws an interpolate frame to fbo, based on the frame timing in t +// flags: bit set of RENDER_FRAME_* flags static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, - struct ra_fbo fbo) + struct ra_fbo fbo, flags) { bool is_new = false; @@ -2855,7 +2866,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, // it manually + reset the queue if not if (p->surfaces[p->surface_now].id == 0) { struct surface *now = &p->surfaces[p->surface_now]; - if (!update_surface(p, t->current, t->frame_id, now)) + if (!update_surface(p, t->current, t->frame_id, now, flags)) return; p->surface_idx = p->surface_now; is_new = true; @@ -2913,7 +2924,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, if (f_id > p->surfaces[p->surface_idx].id) { struct surface *dst = &p->surfaces[surface_dst]; - if (!update_surface(p, f, f_id, dst)) + if (!update_surface(p, f, f_id, dst, flags)) return; p->surface_idx = surface_dst; surface_dst = surface_wrap(surface_dst + 1); @@ -3013,7 +3024,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, } void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, - struct ra_fbo fbo) + struct ra_fbo fbo, int flags) { gl_video_update_options(p); @@ -3056,7 +3067,7 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, } if (interpolate) { - gl_video_interpolate_frame(p, frame, fbo); + gl_video_interpolate_frame(p, frame, fbo, flags); } else { bool is_new = frame->frame_id != p->image.id; @@ -3068,7 +3079,7 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, p->output_tex_valid = false; pass_info_reset(p, !is_new); - if (!pass_render_frame(p, frame->current, frame->frame_id)) + if (!pass_render_frame(p, frame->current, frame->frame_id, flags)) goto done; // For the non-interpolation case, we draw to a single "cache" @@ -3117,15 +3128,20 @@ done: debug_check_gl(p, "after video rendering"); - if (p->osd) { + if (p->osd && (flags & (RENDER_FRAME_SUBS | RENDER_FRAME_OSD))) { // If we haven't actually drawn anything so far, then we technically // need to consider this the start of a new pass. Let's call it a // redraw just because, since it's basically a blank frame anyway if (!has_frame) pass_info_reset(p, true); - pass_draw_osd(p, p->opts.blend_subs ? OSD_DRAW_OSD_ONLY : 0, - p->osd_pts, p->osd_rect, fbo, true); + int osd_flags = p->opts.blend_subs ? OSD_DRAW_OSD_ONLY : 0; + if (!(flags & RENDER_FRAME_SUBS)) + osd_flags |= OSD_DRAW_OSD_ONLY; + if (!(flags & RENDER_FRAME_OSD)) + osd_flags |= OSD_DRAW_SUB_ONLY; + + pass_draw_osd(p, osd_flags, p->osd_pts, p->osd_rect, fbo, true); debug_check_gl(p, "after OSD rendering"); } diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h index dad6d447f6..cd17308810 100644 --- a/video/out/gpu/video.h +++ b/video/out/gpu/video.h @@ -147,6 +147,12 @@ extern const struct m_sub_options gl_video_conf; struct gl_video; struct vo_frame; +enum { + RENDER_FRAME_SUBS = 1 << 0, + RENDER_FRAME_OSD = 2 << 0, + RENDER_FRAME_DEF = RENDER_FRAME_SUBS | RENDER_FRAME_OSD, +}; + struct gl_video *gl_video_init(struct ra *ra, struct mp_log *log, struct mpv_global *g); void gl_video_uninit(struct gl_video *p); @@ -155,7 +161,7 @@ bool gl_video_check_format(struct gl_video *p, int mp_format); void gl_video_config(struct gl_video *p, struct mp_image_params *params); void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b); void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, - struct ra_fbo fbo); + struct ra_fbo fbo, int flags); void gl_video_resize(struct gl_video *p, struct mp_rect *src, struct mp_rect *dst, struct mp_osd_res *osd); diff --git a/video/out/vo_gpu.c b/video/out/vo_gpu.c index c59be48bd0..d3b27ca5bc 100644 --- a/video/out/vo_gpu.c +++ b/video/out/vo_gpu.c @@ -84,7 +84,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) if (!sw->fns->start_frame(sw, &fbo)) return; - gl_video_render_frame(p->renderer, frame, fbo); + gl_video_render_frame(p->renderer, frame, fbo, RENDER_FRAME_DEF); if (!sw->fns->submit_frame(sw, frame)) { MP_ERR(vo, "Failed presenting frame!\n"); return; diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c index c8dab15bb8..f839f0a197 100644 --- a/video/out/vo_opengl_cb.c +++ b/video/out/vo_opengl_cb.c @@ -331,7 +331,7 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h) ra_gl_ctx_resize(sw, vp_w, abs(vp_h), fbo); ra_gl_ctx_start_frame(sw, &target); target.flip = vp_h < 0; - gl_video_render_frame(ctx->renderer, frame, target); + gl_video_render_frame(ctx->renderer, frame, target, RENDER_FRAME_DEF); ra_gl_ctx_submit_frame(sw, frame); reset_gl_state(ctx->gl); diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c index 4322a3f478..2065151b1d 100644 --- a/video/out/vo_rpi.c +++ b/video/out/vo_rpi.c @@ -266,7 +266,7 @@ static void update_osd(struct vo *vo) .flip = true, }; gl_video_set_osd_pts(p->gl_video, p->osd_pts); - gl_video_render_frame(p->gl_video, &frame, target); + gl_video_render_frame(p->gl_video, &frame, target, RENDER_FRAME_DEF); ra_tex_free(p->egl.ra, &target.tex); MP_STATS(vo, "stop rpi_osd"); -- cgit v1.2.3