X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-minigbm.git;a=blobdiff_plain;f=gbm.c;h=a78921c71f4a282111dfe5b70547ee1379704057;hp=483dfcf26e53918553d2b081a52be70fa87061a4;hb=refs%2Fheads%2Fpie-x86_intel;hpb=d224eaa75e53fbe273b90b9e4fc8f8da8acc321f diff --git a/gbm.c b/gbm.c index 483dfcf..a78921c 100644 --- a/gbm.c +++ b/gbm.c @@ -1,171 +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 +#include "drv.h" +#include "gbm_helpers.h" #include "gbm_priv.h" #include "util.h" -/* -gbm_buffer_base.cc: gbm_bo_get_width(bo), -gbm_buffer_base.cc: gbm_bo_get_height(bo), -gbm_buffer_base.cc: gbm_bo_get_stride(bo), -gbm_buffer_base.cc: gbm_bo_get_handle(bo).u32, -gbm_buffer_base.cc: return gbm_bo_get_handle(bo_).u32; -gbm_buffer_base.cc: return gfx::Size(gbm_bo_get_width(bo_), gbm_bo_get_height(bo_)); -gbm_buffer.cc: gbm_bo_destroy(bo()); -gbm_buffer.cc: gbm_bo* bo = gbm_bo_create(device, -gbm_surface.cc: gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy); -gbm_surface.cc: static_cast(gbm_bo_get_user_data(buffer))); -gbm_surface.cc: gbm_surface_release_buffer(native_surface_, current_buffer_); -gbm_surface.cc: gbm_surface_destroy(native_surface_); -gbm_surface.cc: native_surface_ = gbm_surface_create( -gbm_surface.cc: gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_); -gbm_surface.cc: gbm_surface_release_buffer(native_surface_, current_buffer_); -ozone_platform_gbm.cc: device_(gbm_create_device(dri_->get_fd())) {} -ozone_platform_gbm.cc: gbm_device_destroy(device_); -*/ - -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_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_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; - - if (format == GBM_BO_FORMAT_XRGB8888) - format = GBM_FORMAT_XRGB8888; - if (format == GBM_BO_FORMAT_ARGB8888) - format = GBM_FORMAT_ARGB8888; + uint64_t use_flags; - 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; @@ -186,26 +89,57 @@ PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_b { } -PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) +static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) { struct gbm_bo *bo; - int ret; - 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 = 0; - bo->format = format; - bo->handle.u32 = 0; - bo->destroy_user_data = NULL; - bo->user_data = NULL; - - ret = gbm->driver->bo_create(bo, width, height, format, flags); - if (ret) { + 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_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; + + bo = gbm_bo_new(gbm, format); + + if (!bo) + return NULL; + + bo->bo = drv_bo_create_with_modifiers(gbm->drv, width, height, format, modifiers, count); + + if (!bo->bo) { free(bo); return NULL; } @@ -221,70 +155,181 @@ 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 uint32_t -gbm_bo_get_width(struct gbm_bo *bo) +PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, + uint32_t usage) { - return bo->width; + struct gbm_bo *bo; + 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]; + } + + 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, gbm_format, usage)) + return NULL; + + bo = gbm_bo_new(gbm, gbm_format); + + if (!bo) + return NULL; + + bo->bo = drv_bo_import(gbm->drv, &drv_data); + + if (!bo->bo) { + free(bo); + return NULL; + } + + return 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) +{ + uint32_t map_flags; + if (!bo || width == 0 || height == 0 || !stride || !map_data) + return NULL; + + *stride = gbm_bo_get_plane_stride(bo, plane); + 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; + return drv_bo_map(bo->bo, x, y, width, height, map_flags, (struct map_info **)map_data, + plane); +} + +PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) +{ + assert(bo); + drv_bo_unmap(bo->bo, map_data); +} + +PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo) +{ + return drv_bo_get_width(bo->bo); } -PUBLIC uint32_t -gbm_bo_get_height(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo) { - return bo->height; + return drv_bo_get_height(bo->bo); } -PUBLIC uint32_t -gbm_bo_get_stride(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return bo->stride; + return gbm_bo_get_plane_stride(bo, 0); } -PUBLIC uint32_t -gbm_bo_get_format(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) { - return bo->format; + return drv_bo_get_stride_or_tiling(bo->bo); } -PUBLIC struct gbm_device * -gbm_bo_get_device(struct gbm_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 drv_bo_get_num_planes(bo->bo); +} + +PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) { - return bo->handle; + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; } -PUBLIC int -gbm_bo_get_fd(struct gbm_bo *bo) +PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) { - int fd; + return drv_bo_get_plane_fd(bo->bo, plane); +} - if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm), - gbm_bo_get_handle(bo).u32, - DRM_CLOEXEC, - &fd)) - return -1; - else - return fd; +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; }