@@ -346,14 +346,21 @@ static void update_overlays(struct vo *vo, struct mp_osd_res res,
346346 MP_ERR (vo , "Failed recreating OSD texture!\n" );
347347 break ;
348348 }
349- ok = pl_tex_upload ( p -> gpu , & ( struct pl_tex_transfer_params ) {
349+ struct pl_tex_transfer_params upload_params = {
350350 .tex = entry -> tex ,
351351 .rc = { .x1 = item -> packed_w , .y1 = item -> packed_h , },
352352 .row_pitch = item -> packed -> stride [0 ],
353353 .ptr = item -> packed -> planes [0 ],
354- });
354+ };
355+ // Keep the image alive until it's fully read.
356+ if (p -> gpu -> limits .callbacks ) {
357+ upload_params .callback = talloc_free ;
358+ upload_params .priv = mp_image_new_ref (item -> packed );
359+ }
360+ ok = pl_tex_upload (p -> gpu , & upload_params );
355361 if (!ok ) {
356362 MP_ERR (vo , "Failed uploading OSD texture!\n" );
363+ talloc_free (upload_params .priv );
357364 break ;
358365 }
359366
@@ -791,8 +798,12 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
791798 data [n ].buf = buf ;
792799 data [n ].buf_offset = (uint8_t * ) data [n ].pixels - buf -> data ;
793800 data [n ].pixels = NULL ;
794- } else if (gpu -> limits .callbacks ) {
801+ }
802+ // Keep the image alive until it's fully read.
803+ if (gpu -> limits .callbacks ) {
804+ mp_assert (!data [n ].callback );
795805 data [n ].callback = talloc_free ;
806+ mp_assert (!data [n ].priv );
796807 data [n ].priv = mp_image_new_ref (mpi );
797808 }
798809
@@ -804,6 +815,10 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
804815 talloc_free (mpi );
805816 return false;
806817 }
818+
819+ // Without async callback support, we have to poll...
820+ if (!gpu -> limits .callbacks && data [n ].buf )
821+ while (pl_buf_poll (gpu , data [n ].buf , UINT64_MAX ));
807822 }
808823 timer_pool_stop (p -> sw_upload_timer );
809824 p -> sw_upload_perf = timer_pool_measure (p -> sw_upload_timer );
@@ -2150,6 +2165,11 @@ static void cache_uninit(struct priv *p, struct cache *cache)
21502165static void uninit (struct vo * vo )
21512166{
21522167 struct priv * p = vo -> priv ;
2168+
2169+ // Drain any in-flight uploads.
2170+ if (p -> gpu )
2171+ pl_gpu_finish (p -> gpu );
2172+
21532173 pl_queue_destroy (& p -> queue ); // destroy this first
21542174 for (int i = 0 ; i < MP_ARRAY_SIZE (p -> osd_state .entries ); i ++ )
21552175 pl_tex_destroy (p -> gpu , & p -> osd_state .entries [i ].tex );
0 commit comments