X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=exynos.c;h=5862643eff35d3702c2af6f5ebd35e17e8ba8954;hb=cea0b84e41601c80c757e114eea704fe52e36869;hp=6015d75caee07a6008b7540bfbb4768ca4493c63;hpb=1de26dc73c39b8a77c36e50642403fc359e06c73;p=android-x86%2Fexternal-minigbm.git diff --git a/exynos.c b/exynos.c index 6015d75..5862643 100644 --- a/exynos.c +++ b/exynos.c @@ -1,48 +1,112 @@ /* - * 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. */ -#ifdef GBM_EXYNOS +#ifdef DRV_EXYNOS +// clang-format off +#include +#include +#include #include #include #include +// clang-format on -#include "gbm_priv.h" +#include "drv_priv.h" #include "helpers.h" +#include "util.h" -int gbm_exynos_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12 }; + +static int exynos_init(struct driver *drv) +{ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + + return drv_modify_linear_combinations(drv); +} + +static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) { - size_t size = width * height * gbm_bytes_from_format(format); - struct drm_exynos_gem_create gem_create; + size_t plane; + + if (format == DRM_FORMAT_NV12) { + uint32_t chroma_height; + /* V4L2 s5p-mfc requires width to be 16 byte aligned and height 32. */ + width = ALIGN(width, 16); + height = ALIGN(height, 32); + chroma_height = ALIGN(height / 2, 32); + bo->meta.strides[0] = bo->meta.strides[1] = width; + /* MFC v8+ requires 64 byte padding in the end of luma and chroma buffers. */ + bo->meta.sizes[0] = bo->meta.strides[0] * height + 64; + bo->meta.sizes[1] = bo->meta.strides[1] * chroma_height + 64; + bo->meta.offsets[0] = bo->meta.offsets[1] = 0; + bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1]; + } else if (format == DRM_FORMAT_XRGB8888 || format == DRM_FORMAT_ARGB8888) { + bo->meta.strides[0] = drv_stride_from_format(format, width, 0); + bo->meta.total_size = bo->meta.sizes[0] = height * bo->meta.strides[0]; + bo->meta.offsets[0] = 0; + } else { + drv_log("unsupported format %X\n", format); + assert(0); + return -EINVAL; + } + int ret; + for (plane = 0; plane < bo->meta.num_planes; plane++) { + size_t size = bo->meta.sizes[plane]; + struct drm_exynos_gem_create gem_create = { 0 }; - memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = size; - gem_create.flags = EXYNOS_BO_NONCONTIG; + gem_create.size = size; + gem_create.flags = EXYNOS_BO_NONCONTIG; - ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); - if (ret) - return ret; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); + if (ret) { + drv_log("DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", size); + ret = -errno; + goto cleanup_planes; + } - bo->handle.u32 = gem_create.handle; - bo->size = size; - bo->stride = width * gbm_bytes_from_format(format); + bo->handles[plane].u32 = gem_create.handle; + } return 0; + +cleanup_planes: + for (; plane != 0; plane--) { + struct drm_gem_close gem_close = { 0 }; + + gem_close.handle = bo->handles[plane - 1].u32; + int gem_close_ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + if (gem_close_ret) { + drv_log("DRM_IOCTL_GEM_CLOSE failed: %d\n", gem_close_ret); + } + } + + return ret; } -const struct gbm_driver gbm_driver_exynos = -{ +/* + * Use dumb mapping with exynos even though a GEM buffer is created. + * libdrm does the same thing in exynos_drm.c + */ +const struct backend backend_exynos = { .name = "exynos", - .bo_create = gbm_exynos_bo_create, - .bo_destroy = gbm_gem_bo_destroy, - .format_list = { - {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE}, - {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE}, - } + .init = exynos_init, + .bo_create = exynos_bo_create, + .bo_destroy = drv_gem_bo_destroy, + .bo_import = drv_prime_bo_import, + .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; #endif