vo_gpu: add internal ability to skip osd/subs for rendering

Needed for the following commit.
This commit is contained in:
wm4 2018-02-08 01:55:31 +01:00 committed by Kevin Mitchell
parent bff8cfe3f0
commit 7b1e73139f
5 changed files with 40 additions and 18 deletions

View File

@ -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");
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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");