OSDN Git Service

Add new GBM_BO_IMPORT_FD_PLANAR
[android-x86/external-minigbm.git] / drv.c
diff --git a/drv.c b/drv.c
index de5b87f..d4a50ce 100644 (file)
--- a/drv.c
+++ b/drv.c
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mman.h>
 #include <xf86drm.h>
 
 #include "drv_priv.h"
 #include "helpers.h"
 #include "util.h"
 
+#ifdef DRV_AMDGPU
+extern struct backend backend_amdgpu;
+#endif
 extern struct backend backend_cirrus;
 extern struct backend backend_evdi;
 #ifdef DRV_EXYNOS
@@ -51,6 +55,9 @@ static struct backend *drv_get_backend(int fd)
                return NULL;
 
        struct backend *backend_list[] = {
+#ifdef DRV_AMDGPU
+               &backend_amdgpu,
+#endif
                &backend_cirrus,
                &backend_evdi,
 #ifdef DRV_EXYNOS
@@ -244,39 +251,76 @@ void drv_bo_destroy(struct bo *bo)
        free(bo);
 }
 
+void *
+drv_bo_map(struct bo *bo)
+{
+       assert(drv_num_buffers_per_bo(bo) == 1);
+
+       if (!bo->map_data || bo->map_data == MAP_FAILED)
+               bo->map_data = bo->drv->backend->bo_map(bo);
+
+       return bo->map_data;
+}
+
+int
+drv_bo_unmap(struct bo *bo)
+{
+       int ret = -1;
+
+       assert(drv_num_buffers_per_bo(bo) == 1);
+
+       if (bo->map_data && bo->map_data != MAP_FAILED)
+               ret = munmap(bo->map_data, bo->total_size);
+
+       bo->map_data = NULL;
+
+       return ret;
+}
+
 struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
 {
        int ret;
+       size_t plane;
        struct bo *bo;
        struct drm_prime_handle prime_handle;
 
-       memset(&prime_handle, 0, sizeof(prime_handle));
-       prime_handle.fd = data->fd;
+       bo = drv_bo_new(drv, data->width, data->height, data->format);
 
-       /* This function can support only single plane formats. */
-       /* If multi-plane import is desired, new function should be added. */
-       if (drv_num_planes_from_format(data->format) != 1)
+       if (!bo)
                return NULL;
 
-       bo = drv_bo_new(drv, data->width, data->height, data->format);
+       for (plane = 0; plane < bo->num_planes; plane++) {
 
-       ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE,
-                      &prime_handle);
+               memset(&prime_handle, 0, sizeof(prime_handle));
+               prime_handle.fd = data->fds[plane];
 
-       if (ret) {
-               fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
+               ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE,
+                              &prime_handle);
+
+               if (ret) {
+                       fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
                                "(fd=%u)\n", prime_handle.fd);
-               free(bo);
-               return NULL;
-       }
 
-       bo->strides[0] = data->stride;
-       bo->sizes[0] = data->height * data->stride;
-       bo->handles[0].u32 = prime_handle.handle;
+                       if (plane > 0) {
+                               bo->num_planes = plane;
+                               drv_bo_destroy(bo);
+                       } else {
+                               free(bo);
+                       }
 
-       pthread_mutex_lock(&drv->table_lock);
-       drv_increment_reference_count(drv, bo, 0);
-       pthread_mutex_unlock(&drv->table_lock);
+                       return NULL;
+               }
+
+               bo->handles[plane].u32 = prime_handle.handle;
+               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];
+
+               pthread_mutex_lock(&drv->table_lock);
+               drv_increment_reference_count(drv, bo, plane);
+               pthread_mutex_unlock(&drv->table_lock);
+       }
 
        return bo;
 }
@@ -346,3 +390,11 @@ uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane)
         assert(plane < bo->num_planes);
        return bo->format_modifiers[plane];
 }
+
+drv_format_t drv_resolve_format(struct driver *drv, drv_format_t format)
+{
+       if (drv->backend->resolve_format)
+               return drv->backend->resolve_format(format);
+
+       return format;
+}