On Thu, Sep 11, 2014 at 05:59:40PM +0100, Lionel Landwerlin wrote:
When using Mesa and LibVA in the same process, one would like to be able bind buffers from the output of the decoder to a GL texture through an EGLImage.
LibVA can reuse buffers allocated by Gbm through a file descriptor. It will then wrap it into a drm_intel_bo with drm_intel_bo_gem_create_from_prime().
The problem at the moment is that both library get a different drm_intel_bufmgr object when they call drm_intel_bufmgr_gem_init() even though they're using the same drm file descriptor. As a result, instead of manipulating the same buffer object for a given file descriptor, they get 2 different drm_intel_bo objects and 2 different refcounts, leading one of the library to get errors from the kernel on invalid BO when one of the 2 library is done with a shared buffer.
This patch modifies drm_intel_bufmgr_gem_init() so, given a file descriptor, it will look for an already existing drm_intel_bufmgr using the same file descriptor and return that object.
Almost there!
+static void +drm_intel_bufmgr_gem_unref(drm_intel_bufmgr *bufmgr) +{
- drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
- if (atomic_dec_and_test(&bufmgr_gem->refcount)) {
assert(pthread_mutex_lock(&bufmgr_list_mutex) == 0);
Consider thread A destroying its bufmgr on fd, whilst thread B is creating his.
Thread A drops the last reference and so takes the mutex.
But just before it does, thread B leaps in grabs the mutex, searches through the cache, finds its fd, bumps the refcount and leaves with the old bufmgr (not before dropping the lock!).
Thread A resumes with the lock and frees the bufmgr now owned by thread B.
The usual idiom is
static inline void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) { if (obj && !atomic_add_unless(&obj->refcount.refcount, -1, 1)) { struct drm_device *dev = obj->dev;
mutex_lock(&dev->struct_mutex); if (likely(atomic_dec_and_test(&obj->refcount.refcount))) drm_gem_object_free(&obj->refcount); mutex_unlock(&dev->struct_mutex); } }