#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <xf86drm.h>
#include "drv_priv.h"
goto free_buffer_table;
/* Start with a power of 2 number of allocations. */
- drv->backend->combos.allocations = 2;
- drv->backend->combos.size = 0;
- drv->backend->combos.data =
- calloc(drv->backend->combos.allocations, sizeof(struct combination));
- if (!drv->backend->combos.data)
+ drv->combos.allocations = 2;
+ drv->combos.size = 0;
+
+ drv->combos.data = calloc(drv->combos.allocations, sizeof(struct combination));
+ if (!drv->combos.data)
goto free_map_table;
if (drv->backend->init) {
ret = drv->backend->init(drv);
if (ret) {
- free(drv->backend->combos.data);
+ free(drv->combos.data);
goto free_map_table;
}
}
drmHashDestroy(drv->buffer_table);
drmHashDestroy(drv->map_table);
- free(drv->backend->combos.data);
+ free(drv->combos.data);
pthread_mutex_unlock(&drv->driver_lock);
pthread_mutex_destroy(&drv->driver_lock);
return drv->backend->name;
}
-struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage)
+struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t use_flags)
{
struct combination *curr, *best;
- if (format == DRM_FORMAT_NONE || usage == BO_USE_NONE)
+ if (format == DRM_FORMAT_NONE || use_flags == BO_USE_NONE)
return 0;
best = NULL;
uint32_t i;
- for (i = 0; i < drv->backend->combos.size; i++) {
- curr = &drv->backend->combos.data[i];
- if ((format == curr->format) && usage == (curr->usage & usage))
+ for (i = 0; i < drv->combos.size; i++) {
+ curr = &drv->combos.data[i];
+ if ((format == curr->format) && use_flags == (curr->use_flags & use_flags))
if (!best || best->metadata.priority < curr->metadata.priority)
best = curr;
}
}
struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
- uint64_t flags)
+ uint64_t use_flags)
{
struct bo *bo;
bo->width = width;
bo->height = height;
bo->format = format;
- bo->flags = flags;
+ bo->use_flags = use_flags;
bo->num_planes = drv_num_planes_from_format(format);
if (!bo->num_planes) {
}
struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
- uint64_t flags)
+ uint64_t use_flags)
{
int ret;
size_t plane;
struct bo *bo;
- bo = drv_bo_new(drv, width, height, format, flags);
+ bo = drv_bo_new(drv, width, height, format, use_flags);
if (!bo)
return NULL;
- ret = drv->backend->bo_create(bo, width, height, format, flags);
+ ret = drv->backend->bo_create(bo, width, height, format, use_flags);
if (ret) {
free(bo);
{
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++) {
- void *ptr;
-
+ for (plane = 0; plane < bo->num_planes; plane++)
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 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);
+ assert(drv_map_info_destroy(bo) == 0);
bo->drv->backend->bo_destroy(bo);
}
size_t plane;
struct bo *bo;
- bo = drv_bo_new(drv, data->width, data->height, data->format, data->flags);
+ bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags);
if (!bo)
return NULL;
for (plane = 0; plane < bo->num_planes; plane++) {
bo->strides[plane] = data->strides[plane];
bo->offsets[plane] = data->offsets[plane];
- bo->sizes[plane] = data->sizes[plane];
bo->format_modifiers[plane] = data->format_modifiers[plane];
- bo->total_size += data->sizes[plane];
+ if (plane == bo->num_planes - 1 || data->offsets[plane + 1] == 0) {
+ bo->sizes[plane] =
+ lseek(data->fds[plane], 0, SEEK_END) - data->offsets[plane];
+ lseek(data->fds[plane], 0, SEEK_SET);
+ } else {
+ bo->sizes[plane] = data->offsets[plane + 1] - data->offsets[plane];
+ }
+
+ bo->total_size += bo->sizes[plane];
}
return bo;
}
void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
- uint32_t flags, struct map_info **map_data, size_t plane)
+ uint32_t map_flags, struct map_info **map_data, size_t plane)
{
void *ptr;
uint8_t *addr;
size_t offset;
struct map_info *data;
- int prot;
assert(width > 0);
assert(height > 0);
assert(x + width <= drv_bo_get_width(bo));
assert(y + height <= drv_bo_get_height(bo));
- assert(BO_TRANSFER_READ_WRITE & flags);
+ assert(BO_MAP_READ_WRITE & map_flags);
pthread_mutex_lock(&bo->drv->driver_lock);
}
data = calloc(1, sizeof(*data));
- prot = BO_TRANSFER_WRITE & flags ? PROT_WRITE | PROT_READ : PROT_READ;
- addr = bo->drv->backend->bo_map(bo, data, plane, prot);
+ addr = bo->drv->backend->bo_map(bo, data, plane, map_flags);
if (addr == MAP_FAILED) {
*map_data = NULL;
free(data);
int drv_bo_unmap(struct bo *bo, struct map_info *data)
{
- int ret = 0;
-
- assert(data);
- assert(data->refcount >= 0);
+ int ret = drv_bo_flush(bo, data);
+ if (ret)
+ return ret;
pthread_mutex_lock(&bo->drv->driver_lock);
if (!--data->refcount) {
- if (bo->drv->backend->bo_unmap)
- ret = bo->drv->backend->bo_unmap(bo, data);
- else
- ret = munmap(data->addr, data->length);
+ ret = bo->drv->backend->bo_unmap(bo, data);
drmHashDelete(bo->drv->map_table, data->handle);
free(data);
}
return ret;
}
+int drv_bo_flush(struct bo *bo, struct map_info *data)
+{
+ int ret = 0;
+ assert(data);
+ assert(data->refcount >= 0);
+
+ if (bo->drv->backend->bo_flush)
+ ret = bo->drv->backend->bo_flush(bo, data);
+
+ return ret;
+}
+
uint32_t drv_bo_get_width(struct bo *bo)
{
return bo->width;
return bo->format;
}
-uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t usage)
+uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags)
{
if (drv->backend->resolve_format)
- return drv->backend->resolve_format(format, usage);
+ return drv->backend->resolve_format(format, use_flags);
return format;
}
return 0;
}
-uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane)
-{
- assert(plane < drv_num_planes_from_format(format));
- uint32_t vertical_subsampling;
-
- switch (format) {
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_YVU420:
- case DRM_FORMAT_YVU420_ANDROID:
- vertical_subsampling = (plane == 0) ? 1 : 2;
- break;
- default:
- vertical_subsampling = 1;
- }
-
- return stride * DIV_ROUND_UP(height, vertical_subsampling);
-}
-
uint32_t drv_num_buffers_per_bo(struct bo *bo)
{
uint32_t count = 0;