X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=gbm.c;h=c12c26915e105e16327fc8c0b16ce88da387a739;hb=1c4a1cf7e48264011549b6da1b1588a8ff076a11;hp=10b0bcde2de8339e618e0f40b904bb845152a9e9;hpb=f4bfdbaee1fa0212928b83c839a178872bd7f688;p=android-x86%2Fexternal-minigbm.git diff --git a/gbm.c b/gbm.c index 10b0bcd..c12c269 100644 --- a/gbm.c +++ b/gbm.c @@ -1,162 +1,74 @@ /* - * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Copyright 2014 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include #include #include #include #include #include +#include #include +#include "drv.h" +#include "gbm_helpers.h" #include "gbm_priv.h" -#include "helpers.h" #include "util.h" -extern struct gbm_driver gbm_driver_cirrus; -#ifdef GBM_EXYNOS -extern struct gbm_driver gbm_driver_exynos; -#endif -extern struct gbm_driver gbm_driver_gma500; -#ifdef GBM_I915 -extern struct gbm_driver gbm_driver_i915; -#endif -#ifdef GBM_MEDIATEK -extern struct gbm_driver gbm_driver_mediatek; -#endif -#ifdef GBM_ROCKCHIP -extern struct gbm_driver gbm_driver_rockchip; -#endif -#ifdef GBM_TEGRA -extern struct gbm_driver gbm_driver_tegra; -#endif -extern struct gbm_driver gbm_driver_udl; - -static struct gbm_driver *gbm_get_driver(int fd) -{ - drmVersionPtr drm_version; - unsigned int i; - - drm_version = drmGetVersion(fd); - - if (!drm_version) - return NULL; - - struct gbm_driver *driver_list[] = { - &gbm_driver_cirrus, -#ifdef GBM_EXYNOS - &gbm_driver_exynos, -#endif - &gbm_driver_gma500, -#ifdef GBM_I915 - &gbm_driver_i915, -#endif -#ifdef GBM_MEDIATEK - &gbm_driver_mediatek, -#endif -#ifdef GBM_ROCKCHIP - &gbm_driver_rockchip, -#endif -#ifdef GBM_TEGRA - &gbm_driver_tegra, -#endif - &gbm_driver_udl, - }; - - for(i = 0; i < ARRAY_SIZE(driver_list); i++) - if (!strcmp(drm_version->name, driver_list[i]->name)) - { - drmFreeVersion(drm_version); - return driver_list[i]; - } - - drmFreeVersion(drm_version); - return NULL; -} - -PUBLIC int -gbm_device_get_fd(struct gbm_device *gbm) +PUBLIC int gbm_device_get_fd(struct gbm_device *gbm) { - return gbm->fd; + + return drv_get_fd(gbm->drv); } -PUBLIC const char * -gbm_device_get_backend_name(struct gbm_device *gbm) +PUBLIC const char *gbm_device_get_backend_name(struct gbm_device *gbm) { - return gbm->driver->name; + return drv_get_name(gbm->drv); } -PUBLIC int -gbm_device_is_format_supported(struct gbm_device *gbm, - uint32_t format, uint32_t usage) +PUBLIC int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage) { - unsigned i; + uint64_t use_flags; - if (format == GBM_BO_FORMAT_XRGB8888) - format = GBM_FORMAT_XRGB8888; - if (format == GBM_BO_FORMAT_ARGB8888) - format = GBM_FORMAT_ARGB8888; - - if (usage & GBM_BO_USE_CURSOR && - usage & GBM_BO_USE_RENDERING) + if (usage & GBM_BO_USE_CURSOR && usage & GBM_BO_USE_RENDERING) return 0; - for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++) - { - if (!gbm->driver->format_list[i].format) - break; + use_flags = gbm_convert_usage(usage); - if (gbm->driver->format_list[i].format == format && - (gbm->driver->format_list[i].usage & usage) == usage) - return 1; - } - - return 0; + return (drv_get_combination(gbm->drv, format, use_flags) != NULL); } PUBLIC struct gbm_device *gbm_create_device(int fd) { struct gbm_device *gbm; - int ret; - gbm = (struct gbm_device*) malloc(sizeof(*gbm)); + gbm = (struct gbm_device *)malloc(sizeof(*gbm)); + if (!gbm) return NULL; - gbm->fd = fd; - - gbm->driver = gbm_get_driver(fd); - if (!gbm->driver) { + gbm->drv = drv_create(fd); + if (!gbm->drv) { free(gbm); return NULL; } - if (gbm->driver->init) { - ret = gbm->driver->init(gbm); - if (ret) { - free(gbm); - return NULL; - } - } - return gbm; } PUBLIC void gbm_device_destroy(struct gbm_device *gbm) { - if (gbm->driver->close) - gbm->driver->close(gbm); + drv_destroy(gbm->drv); free(gbm); } -PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, + uint32_t height, uint32_t format, uint32_t usage) { - struct gbm_surface *surface = - (struct gbm_surface*) malloc(sizeof(*surface)); + struct gbm_surface *surface = (struct gbm_surface *)malloc(sizeof(*surface)); if (!surface) return NULL; @@ -174,47 +86,61 @@ PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface) return NULL; } -PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, - struct gbm_bo *bo) +PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo) { } -static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t stride) +static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) { struct gbm_bo *bo; - bo = (struct gbm_bo*) malloc(sizeof(*bo)); + bo = (struct gbm_bo *)calloc(1, sizeof(*bo)); if (!bo) return NULL; bo->gbm = gbm; - bo->width = width; - bo->height = height; - bo->stride = stride; - bo->format = format; - bo->handle.u32 = 0; - bo->destroy_user_data = NULL; - bo->user_data = NULL; + bo->gbm_format = format; + + return bo; +} + +PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, + uint32_t format, uint32_t usage) +{ + struct gbm_bo *bo; + + if (!gbm_device_is_format_supported(gbm, format, usage)) + return NULL; + + bo = gbm_bo_new(gbm, format); + + if (!bo) + return NULL; + + bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_usage(usage)); + + if (!bo->bo) { + free(bo); + return NULL; + } return bo; } -PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, - uint32_t height, uint32_t format, - uint32_t flags) +PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers(struct gbm_device *gbm, uint32_t width, + uint32_t height, uint32_t format, + const uint64_t *modifiers, uint32_t count) { struct gbm_bo *bo; - int ret; - bo = gbm_bo_new(gbm, width, height, format, - width * gbm_bytes_from_format(format)); + bo = gbm_bo_new(gbm, format); + if (!bo) return NULL; - ret = gbm->driver->bo_create(bo, width, height, format, flags); - if (ret) { + bo->bo = drv_bo_create_with_modifiers(gbm->drv, width, height, format, modifiers, count); + + if (!bo->bo) { free(bo); return NULL; } @@ -230,111 +156,191 @@ PUBLIC void gbm_bo_destroy(struct gbm_bo *bo) bo->user_data = NULL; } - bo->gbm->driver->bo_destroy(bo); + drv_bo_destroy(bo->bo); free(bo); } -PUBLIC struct gbm_bo * -gbm_bo_import(struct gbm_device *gbm, uint32_t type, - void *buffer, uint32_t usage) +PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, + uint32_t usage) { - struct gbm_import_fd_data *fd_data = buffer; struct gbm_bo *bo; - struct drm_prime_handle prime_handle; - int ret; + struct drv_import_fd_data drv_data; + struct gbm_import_fd_data *fd_data = buffer; + struct gbm_import_fd_planar_data *fd_planar_data = buffer; + uint32_t gbm_format; + size_t num_planes, i; + + memset(&drv_data, 0, sizeof(drv_data)); + drv_data.use_flags = gbm_convert_usage(usage); + switch (type) { + case GBM_BO_IMPORT_FD: + gbm_format = fd_data->format; + drv_data.width = fd_data->width; + drv_data.height = fd_data->height; + drv_data.format = fd_data->format; + drv_data.fds[0] = fd_data->fd; + drv_data.strides[0] = fd_data->stride; + break; + case GBM_BO_IMPORT_FD_PLANAR: + gbm_format = fd_planar_data->format; + drv_data.width = fd_planar_data->width; + drv_data.height = fd_planar_data->height; + drv_data.format = fd_planar_data->format; + num_planes = drv_num_planes_from_format(drv_data.format); + + assert(num_planes); + + for (i = 0; i < num_planes; i++) { + drv_data.fds[i] = fd_planar_data->fds[i]; + drv_data.offsets[i] = fd_planar_data->offsets[i]; + drv_data.strides[i] = fd_planar_data->strides[i]; + drv_data.format_modifiers[i] = fd_planar_data->format_modifiers[i]; + } - if (type != GBM_BO_IMPORT_FD) + for (i = num_planes; i < GBM_MAX_PLANES; i++) + drv_data.fds[i] = -1; + + break; + default: return NULL; + } - if (!gbm_device_is_format_supported(gbm, fd_data->format, usage)) + if (!gbm_device_is_format_supported(gbm, gbm_format, usage)) return NULL; - bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format, - fd_data->stride); + bo = gbm_bo_new(gbm, gbm_format); + if (!bo) return NULL; - prime_handle.fd = fd_data->fd; + bo->bo = drv_bo_import(gbm->drv, &drv_data); - ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle); - if (ret) { - fprintf(stderr, "minigbm: DRM_IOCTL_PRIME_FD_TO_HANDLE failed " - "(fd=%u)\n", prime_handle.fd); + if (!bo->bo) { free(bo); return NULL; } - bo->handle.u32 = prime_handle.handle; - return bo; } -PUBLIC uint32_t -gbm_bo_get_width(struct gbm_bo *bo) +PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t transfer_flags, uint32_t *stride, void **map_data, size_t plane) { - return bo->width; + void *addr; + off_t offset; + uint32_t map_flags; + struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; + if (!bo || width == 0 || height == 0 || !stride || !map_data) + return NULL; + + map_flags = (transfer_flags & GBM_BO_TRANSFER_READ) ? BO_MAP_READ : BO_MAP_NONE; + map_flags |= (transfer_flags & GBM_BO_TRANSFER_WRITE) ? BO_MAP_WRITE : BO_MAP_NONE; + + addr = drv_bo_map(bo->bo, &rect, map_flags, (struct mapping **)map_data, plane); + if (addr == MAP_FAILED) + return MAP_FAILED; + + *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; + + offset = *stride * rect.y; + offset += drv_stride_from_format(bo->gbm_format, rect.x, plane); + return (void *)((uint8_t *)addr + offset); } -PUBLIC uint32_t -gbm_bo_get_height(struct gbm_bo *bo) +PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) { - return bo->height; + assert(bo); + drv_bo_flush_or_unmap(bo->bo, map_data); } -PUBLIC uint32_t -gbm_bo_get_stride(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo) { - return bo->stride; + return drv_bo_get_width(bo->bo); } -PUBLIC uint32_t -gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo) { - return bo->tiling ? bo->tiling : bo->stride; + return drv_bo_get_height(bo->bo); } -PUBLIC uint32_t -gbm_bo_get_format(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return bo->format; + return gbm_bo_get_plane_stride(bo, 0); } -PUBLIC struct gbm_device * -gbm_bo_get_device(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) +{ + return drv_bo_get_stride_or_tiling(bo->bo); +} + +PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo) +{ + return bo->gbm_format; +} + +PUBLIC uint64_t gbm_bo_get_format_modifier(struct gbm_bo *bo) +{ + return gbm_bo_get_plane_format_modifier(bo, 0); +} + +PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) { return bo->gbm; } -PUBLIC union gbm_bo_handle -gbm_bo_get_handle(struct gbm_bo *bo) +PUBLIC union gbm_bo_handle gbm_bo_get_handle(struct gbm_bo *bo) +{ + return gbm_bo_get_plane_handle(bo, 0); +} + +PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo) +{ + return gbm_bo_get_plane_fd(bo, 0); +} + +PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) { - return bo->handle; + return drv_bo_get_num_planes(bo->bo); } -PUBLIC int -gbm_bo_get_fd(struct gbm_bo *bo) +PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) { - int fd; + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; +} - if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm), - gbm_bo_get_handle(bo).u32, - DRM_CLOEXEC, - &fd)) - return -1; - else - return fd; +PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_fd(bo->bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_offset(bo->bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_size(bo->bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_stride(bo->bo, plane); +} + +PUBLIC uint64_t gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_format_modifier(bo->bo, plane); } -PUBLIC void -gbm_bo_set_user_data(struct gbm_bo *bo, void *data, - void (*destroy_user_data)(struct gbm_bo *, void *)) +PUBLIC void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, + void (*destroy_user_data)(struct gbm_bo *, void *)) { bo->user_data = data; bo->destroy_user_data = destroy_user_data; } -PUBLIC void * -gbm_bo_get_user_data(struct gbm_bo *bo) +PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo) { return bo->user_data; }