On Wed, Aug 13, 2014 at 11:07 AM, Christian König <deathsim...@vodafone.de> wrote: > From: Christian König <christian.koe...@amd.com> > > This fixes an issue with flash where it tries to destroy a decoder > after already destroying the device associated with the decoder. > > Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=82517 > > Signed-off-by: Christian König <christian.koe...@amd.com>
Have you considered the opposite approach -- tearing everything down when the device is torn down, instead of keeping the device alive longer? Any idea what NVIDIA does? (Do the VDPAU docs say anything about this? I don't see it anywhere.) The reason I bring it up is that now an application that doesn't destroy everything about a device will end up leaking it, which may be a heavier object to leak than just surfaces or something. > --- > src/gallium/state_trackers/vdpau/bitmap.c | 4 +++- > src/gallium/state_trackers/vdpau/decode.c | 4 +++- > src/gallium/state_trackers/vdpau/device.c | 21 ++++++++++++++++----- > src/gallium/state_trackers/vdpau/mixer.c | 4 +++- > src/gallium/state_trackers/vdpau/output.c | 4 +++- > src/gallium/state_trackers/vdpau/presentation.c | 4 +++- > src/gallium/state_trackers/vdpau/surface.c | 4 +++- > src/gallium/state_trackers/vdpau/vdpau_private.h | 12 ++++++++++++ > 8 files changed, 46 insertions(+), 11 deletions(-) > > diff --git a/src/gallium/state_trackers/vdpau/bitmap.c > b/src/gallium/state_trackers/vdpau/bitmap.c > index a068921..97a4287 100644 > --- a/src/gallium/state_trackers/vdpau/bitmap.c > +++ b/src/gallium/state_trackers/vdpau/bitmap.c > @@ -67,7 +67,7 @@ vlVdpBitmapSurfaceCreate(VdpDevice device, > if (!vlsurface) > return VDP_STATUS_RESOURCES; > > - vlsurface->device = dev; > + DeviceReference(&vlsurface->device, dev); > > memset(&res_tmpl, 0, sizeof(res_tmpl)); > res_tmpl.target = PIPE_TEXTURE_2D; > @@ -117,6 +117,7 @@ err_sampler: > pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); > err_unlock: > pipe_mutex_unlock(dev->mutex); > + DeviceReference(&vlsurface->device, NULL); > FREE(vlsurface); > return ret; > } > @@ -138,6 +139,7 @@ vlVdpBitmapSurfaceDestroy(VdpBitmapSurface surface) > pipe_mutex_unlock(vlsurface->device->mutex); > > vlRemoveDataHTAB(surface); > + DeviceReference(&vlsurface->device, NULL); > FREE(vlsurface); > > return VDP_STATUS_OK; > diff --git a/src/gallium/state_trackers/vdpau/decode.c > b/src/gallium/state_trackers/vdpau/decode.c > index 1e5f81e..767d311 100644 > --- a/src/gallium/state_trackers/vdpau/decode.c > +++ b/src/gallium/state_trackers/vdpau/decode.c > @@ -110,7 +110,7 @@ vlVdpDecoderCreate(VdpDevice device, > return VDP_STATUS_RESOURCES; > } > > - vldecoder->device = dev; > + DeviceReference(&vldecoder->device, dev); > > templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; > templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; > @@ -141,6 +141,7 @@ error_handle: > > error_decoder: > pipe_mutex_unlock(dev->mutex); > + DeviceReference(&vldecoder->device, NULL); > FREE(vldecoder); > return ret; > } > @@ -163,6 +164,7 @@ vlVdpDecoderDestroy(VdpDecoder decoder) > pipe_mutex_destroy(vldecoder->mutex); > > vlRemoveDataHTAB(decoder); > + DeviceReference(&vldecoder->device, NULL); > FREE(vldecoder); > > return VDP_STATUS_OK; > diff --git a/src/gallium/state_trackers/vdpau/device.c > b/src/gallium/state_trackers/vdpau/device.c > index 0cdda73..9c5ec60 100644 > --- a/src/gallium/state_trackers/vdpau/device.c > +++ b/src/gallium/state_trackers/vdpau/device.c > @@ -59,6 +59,8 @@ vdp_imp_device_create_x11(Display *display, int screen, > VdpDevice *device, > goto no_dev; > } > > + pipe_reference_init(&dev->reference, 1); > + > dev->vscreen = vl_screen_create(display, screen); > if (!dev->vscreen) { > ret = VDP_STATUS_RESOURCES; > @@ -124,7 +126,7 @@ vlVdpPresentationQueueTargetCreateX11(VdpDevice device, > Drawable drawable, > if (!pqt) > return VDP_STATUS_RESOURCES; > > - pqt->device = dev; > + DeviceReference(&pqt->device, dev); > pqt->drawable = drawable; > > *target = vlAddDataHTAB(pqt); > @@ -153,6 +155,7 @@ > vlVdpPresentationQueueTargetDestroy(VdpPresentationQueueTarget > presentation_queu > return VDP_STATUS_INVALID_HANDLE; > > vlRemoveDataHTAB(presentation_queue_target); > + DeviceReference(&pqt->device, NULL); > FREE(pqt); > > return VDP_STATUS_OK; > @@ -168,16 +171,24 @@ vlVdpDeviceDestroy(VdpDevice device) > if (!dev) > return VDP_STATUS_INVALID_HANDLE; > > + vlRemoveDataHTAB(device); > + DeviceReference(&dev, NULL); > + > + return VDP_STATUS_OK; > +} > + > +/** > + * Free a VdpDevice. > + */ > +void > +vlVdpDeviceFree(vlVdpDevice *dev) > +{ > pipe_mutex_destroy(dev->mutex); > vl_compositor_cleanup(&dev->compositor); > dev->context->destroy(dev->context); > vl_screen_destroy(dev->vscreen); > - > - vlRemoveDataHTAB(device); > FREE(dev); > vlDestroyHTAB(); > - > - return VDP_STATUS_OK; > } > > /** > diff --git a/src/gallium/state_trackers/vdpau/mixer.c > b/src/gallium/state_trackers/vdpau/mixer.c > index e6bfb8c..a724aa5 100644 > --- a/src/gallium/state_trackers/vdpau/mixer.c > +++ b/src/gallium/state_trackers/vdpau/mixer.c > @@ -60,7 +60,7 @@ vlVdpVideoMixerCreate(VdpDevice device, > if (!vmixer) > return VDP_STATUS_RESOURCES; > > - vmixer->device = dev; > + DeviceReference(&vmixer->device, dev); > > pipe_mutex_lock(dev->mutex); > > @@ -160,6 +160,7 @@ no_params: > no_handle: > vl_compositor_cleanup_state(&vmixer->cstate); > pipe_mutex_unlock(dev->mutex); > + DeviceReference(&vmixer->device, NULL); > FREE(vmixer); > return ret; > } > @@ -199,6 +200,7 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer) > FREE(vmixer->sharpness.filter); > } > pipe_mutex_unlock(vmixer->device->mutex); > + DeviceReference(&vmixer->device, NULL); > > FREE(vmixer); > > diff --git a/src/gallium/state_trackers/vdpau/output.c > b/src/gallium/state_trackers/vdpau/output.c > index 457f678..caae50f 100644 > --- a/src/gallium/state_trackers/vdpau/output.c > +++ b/src/gallium/state_trackers/vdpau/output.c > @@ -69,7 +69,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device, > if (!vlsurface) > return VDP_STATUS_RESOURCES; > > - vlsurface->device = dev; > + DeviceReference(&vlsurface->device, dev); > > memset(&res_tmpl, 0, sizeof(res_tmpl)); > > @@ -120,6 +120,7 @@ err_resource: > pipe_resource_reference(&res, NULL); > err_unlock: > pipe_mutex_unlock(dev->mutex); > + DeviceReference(&vlsurface->device, NULL); > FREE(vlsurface); > return VDP_STATUS_ERROR; > } > @@ -149,6 +150,7 @@ vlVdpOutputSurfaceDestroy(VdpOutputSurface surface) > pipe_mutex_unlock(vlsurface->device->mutex); > > vlRemoveDataHTAB(surface); > + DeviceReference(&vlsurface->device, NULL); > FREE(vlsurface); > > return VDP_STATUS_OK; > diff --git a/src/gallium/state_trackers/vdpau/presentation.c > b/src/gallium/state_trackers/vdpau/presentation.c > index cb6cb38..7f8dbed 100644 > --- a/src/gallium/state_trackers/vdpau/presentation.c > +++ b/src/gallium/state_trackers/vdpau/presentation.c > @@ -62,7 +62,7 @@ vlVdpPresentationQueueCreate(VdpDevice device, > if (!pq) > return VDP_STATUS_RESOURCES; > > - pq->device = dev; > + DeviceReference(&pq->device, dev); > pq->drawable = pqt->drawable; > > pipe_mutex_lock(dev->mutex); > @@ -83,6 +83,7 @@ vlVdpPresentationQueueCreate(VdpDevice device, > > no_handle: > no_compositor: > + DeviceReference(&pq->device, NULL); > FREE(pq); > return ret; > } > @@ -104,6 +105,7 @@ vlVdpPresentationQueueDestroy(VdpPresentationQueue > presentation_queue) > pipe_mutex_unlock(pq->device->mutex); > > vlRemoveDataHTAB(presentation_queue); > + DeviceReference(&pq->device, NULL); > FREE(pq); > > return VDP_STATUS_OK; > diff --git a/src/gallium/state_trackers/vdpau/surface.c > b/src/gallium/state_trackers/vdpau/surface.c > index 0d9f2b0..1932cdd 100644 > --- a/src/gallium/state_trackers/vdpau/surface.c > +++ b/src/gallium/state_trackers/vdpau/surface.c > @@ -74,7 +74,7 @@ vlVdpVideoSurfaceCreate(VdpDevice device, VdpChromaType > chroma_type, > goto inv_device; > } > > - p_surf->device = dev; > + DeviceReference(&p_surf->device, dev); > pipe = dev->context; > > pipe_mutex_lock(dev->mutex); > @@ -115,6 +115,7 @@ no_handle: > p_surf->video_buffer->destroy(p_surf->video_buffer); > > inv_device: > + DeviceReference(&p_surf->device, NULL); > FREE(p_surf); > > no_res: > @@ -140,6 +141,7 @@ vlVdpVideoSurfaceDestroy(VdpVideoSurface surface) > pipe_mutex_unlock(p_surf->device->mutex); > > vlRemoveDataHTAB(surface); > + DeviceReference(&p_surf->device, NULL); > FREE(p_surf); > > return VDP_STATUS_OK; > diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h > b/src/gallium/state_trackers/vdpau/vdpau_private.h > index ce6852b..65f8e47 100644 > --- a/src/gallium/state_trackers/vdpau/vdpau_private.h > +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h > @@ -344,6 +344,7 @@ CheckSurfaceParams(struct pipe_screen *screen, > > typedef struct > { > + struct pipe_reference reference; > struct vl_screen *vscreen; > struct pipe_context *context; > struct vl_compositor compositor; > @@ -453,6 +454,7 @@ void vlVdpSave4DelayedRendering(vlVdpDevice *dev, > VdpOutputSurface surface, stru > /* Internal function pointers */ > VdpGetErrorString vlVdpGetErrorString; > VdpDeviceDestroy vlVdpDeviceDestroy; > +void vlVdpDeviceFree(vlVdpDevice *dev); > VdpGetProcAddress vlVdpGetProcAddress; > VdpGetApiVersion vlVdpGetApiVersion; > VdpGetInformationString vlVdpGetInformationString; > @@ -542,4 +544,14 @@ static inline void VDPAU_MSG(unsigned int level, const > char *fmt, ...) > } > } > > +static inline void > +DeviceReference(vlVdpDevice **ptr, vlVdpDevice *dev) > +{ > + vlVdpDevice *old_dev = *ptr; > + > + if (pipe_reference(&(*ptr)->reference, &dev->reference)) > + vlVdpDeviceFree(old_dev); > + *ptr = dev; > +} > + > #endif /* VDPAU_PRIVATE_H */ > -- > 1.9.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev