vo_gpu_next: don't flush cache on OSD update

Flushing the cache is a hammer-for-a-screw operation, because it nukes
*all* renderer state, including the HDR peak detection state. When
enabling e.g. --hdr-compute-peak, or any other future methods of dynamic
tone mapping, this would lead to bad results (e.g. brightness
fluctuations) whenever the OSD state is updated.

Instead of flushing the cache to force an OSD re-render, instead just
update the frame signature directly whenever its osd_sync value changes.
This accomplishes effectively the same thing but without touching the
HDR state.

This is slightly violating the libplacebo abstraction in a way that
isn't publicly documented. To be on the safe side we could make a carbon
copy of the array before modifying it, but given that this is unlikely
to change upstream I'll probably just end up explicitly documenting it
instead of forcing the copy in mpv.
This commit is contained in:
Niklas Haas 2022-11-23 14:58:16 +01:00 committed by Niklas Haas
parent ead8469454
commit e97e0e4d92
1 changed files with 9 additions and 2 deletions

View File

@ -982,6 +982,15 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
image->num_overlays = 0;
fp->osd_sync = 0;
}
// Update the frame signature to include the current OSD sync
// value, in order to disambiguate between identical frames with
// modified OSD. Shift the OSD sync value by a lot to avoid
// collisions with low signature values.
//
// This is safe to do because `pl_frame_mix.signature` lives in
// temporary memory that is only valid for this `pl_queue_update`.
((uint64_t *) mix.signatures)[i] ^= fp->osd_sync << 48;
}
}
@ -1063,7 +1072,6 @@ static void resize(struct vo *vo)
osd_res_equals(p->osd_res, osd))
return;
pl_renderer_flush_cache(p->rr);
p->osd_sync++;
p->osd_res = osd;
p->src = src;
@ -1244,7 +1252,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
return VO_TRUE;
case VOCTRL_OSD_CHANGED:
pl_renderer_flush_cache(p->rr);
p->osd_sync++;
return VO_TRUE;