OSDN Git Service

minigbm: pass in map flags to (*bo_map) callback
[android-x86/external-minigbm.git] / drv.c
diff --git a/drv.c b/drv.c
index 10a6348..b7a8f91 100644 (file)
--- a/drv.c
+++ b/drv.c
@@ -12,6 +12,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
 #include <xf86drm.h>
 
 #include "drv_priv.h"
@@ -136,17 +138,17 @@ struct driver *drv_create(int fd)
                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;
                }
        }
@@ -174,7 +176,7 @@ void drv_destroy(struct driver *drv)
        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);
@@ -192,18 +194,18 @@ const char *drv_get_name(struct driver *drv)
        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;
        }
@@ -212,7 +214,7 @@ struct combination *drv_get_combination(struct driver *drv, uint32_t format, uin
 }
 
 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;
@@ -225,7 +227,7 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3
        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) {
@@ -237,18 +239,18 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3
 }
 
 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);
@@ -303,7 +305,6 @@ void drv_bo_destroy(struct bo *bo)
 {
        size_t plane;
        uintptr_t total = 0;
-       size_t map_count = 0;
        struct driver *drv = bo->drv;
 
        pthread_mutex_lock(&drv->driver_lock);
@@ -311,22 +312,13 @@ void drv_bo_destroy(struct bo *bo)
        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);
        }
 
@@ -339,7 +331,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
        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;
@@ -353,28 +345,34 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
        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);
 
@@ -385,8 +383,7 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t
        }
 
        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);
@@ -412,18 +409,14 @@ success:
 
 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);
        }
@@ -433,6 +426,18 @@ int drv_bo_unmap(struct bo *bo, struct map_info *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;
@@ -502,10 +507,10 @@ uint32_t drv_bo_get_format(struct bo *bo)
        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;
 }
@@ -573,24 +578,6 @@ size_t drv_num_planes_from_format(uint32_t 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;