return best;
}
-struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format)
+struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
+ uint64_t flags)
{
struct bo *bo;
bo->width = width;
bo->height = height;
bo->format = format;
+ bo->flags = flags;
bo->num_planes = drv_num_planes_from_format(format);
if (!bo->num_planes) {
size_t plane;
struct bo *bo;
- bo = drv_bo_new(drv, width, height, format);
+ bo = drv_bo_new(drv, width, height, format, flags);
if (!bo)
return NULL;
return NULL;
}
- bo = drv_bo_new(drv, width, height, format);
+ bo = drv_bo_new(drv, width, height, format, BO_USE_NONE);
if (!bo)
return NULL;
{
size_t plane;
uintptr_t total = 0;
+ size_t map_count = 0;
struct driver *drv = bo->drv;
pthread_mutex_lock(&drv->driver_lock);
for (plane = 0; plane < bo->num_planes; plane++)
drv_decrement_reference_count(drv, bo, plane);
- for (plane = 0; plane < bo->num_planes; plane++)
+ for (plane = 0; plane < bo->num_planes; plane++) {
+ void *ptr;
+
total += drv_get_reference_count(drv, bo, plane);
+ map_count += !drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr);
+ }
pthread_mutex_unlock(&drv->driver_lock);
- if (total == 0)
+ if (total == 0) {
+ /*
+ * If we leak a reference to the GEM handle being freed here in the mapping table,
+ * we risk using the mapping table entry later for a completely different BO that
+ * gets the same handle. (See b/38250067.)
+ */
+ assert(!map_count);
bo->drv->backend->bo_destroy(bo);
+ }
free(bo);
}
size_t plane;
struct bo *bo;
- bo = drv_bo_new(drv, data->width, data->height, data->format);
+ bo = drv_bo_new(drv, data->width, data->height, data->format, data->flags);
if (!bo)
return NULL;