diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/third_party/minigbm | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/minigbm')
46 files changed, 2361 insertions, 2125 deletions
diff --git a/chromium/third_party/minigbm/src/.clang-format b/chromium/third_party/minigbm/src/.clang-format new file mode 100644 index 00000000000..6628ecda0a1 --- /dev/null +++ b/chromium/third_party/minigbm/src/.clang-format @@ -0,0 +1,15 @@ +# Copyright 2017 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. + +BasedOnStyle: LLVM +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +BreakBeforeBraces: Linux +ColumnLimit: 100 +IndentWidth: 8 +TabWidth: 8 +UseTab: Always +Cpp11BracedListStyle: false +IndentCaseLabels: false diff --git a/chromium/third_party/minigbm/src/Android.gralloc.mk b/chromium/third_party/minigbm/src/Android.gralloc.mk new file mode 100644 index 00000000000..ff269c00aed --- /dev/null +++ b/chromium/third_party/minigbm/src/Android.gralloc.mk @@ -0,0 +1,11 @@ +# Copyright 2017 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. + +LOCAL_CPP_EXTENSION := .cc + +LOCAL_SRC_FILES += \ + cros_gralloc/cros_gralloc_buffer.cc \ + cros_gralloc/cros_gralloc_driver.cc \ + cros_gralloc/cros_gralloc_helpers.cc \ + cros_gralloc/gralloc0/gralloc0.cc diff --git a/chromium/third_party/minigbm/src/Android.mk b/chromium/third_party/minigbm/src/Android.mk new file mode 100644 index 00000000000..c4798adb197 --- /dev/null +++ b/chromium/third_party/minigbm/src/Android.mk @@ -0,0 +1,59 @@ +# Copyright 2017 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. + +ifeq ($(strip $(BOARD_USES_MINIGBM)), true) + +MINIGBM_GRALLOC_MK := $(call my-dir)/Android.gralloc.mk +LOCAL_PATH := $(call my-dir) +intel_drivers := i915 i965 +include $(CLEAR_VARS) + +SUBDIRS := cros_gralloc + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libdrm + +LOCAL_SRC_FILES := \ + amdgpu.c \ + cirrus.c \ + drv.c \ + evdi.c \ + exynos.c \ + gma500.c \ + helpers.c \ + i915.c \ + marvell.c \ + mediatek.c \ + nouveau.c \ + rockchip.c \ + tegra.c \ + udl.c \ + vc4.c \ + vgem.c \ + virtio_gpu.c + +include $(MINIGBM_GRALLOC_MK) + +LOCAL_CPPFLAGS += -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 +LOCAL_CFLAGS += -Wall -Wsign-compare -Wpointer-arith \ + -Wcast-qual -Wcast-align \ + -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 + +ifneq ($(filter $(intel_drivers), $(BOARD_GPU_DRIVERS)),) +LOCAL_CPPFLAGS += -DDRV_I915 +LOCAL_CFLAGS += -DDRV_I915 +LOCAL_SHARED_LIBRARIES += libdrm_intel +endif + +LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE_TAGS := optional +# The preferred path for vendor HALs is /vendor/lib/hw +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX) +include $(BUILD_SHARED_LIBRARY) + +#endif diff --git a/chromium/third_party/minigbm/src/LICENSE b/chromium/third_party/minigbm/src/LICENSE new file mode 100644 index 00000000000..3bd5095873d --- /dev/null +++ b/chromium/third_party/minigbm/src/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2017 The Chromium OS Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/chromium/third_party/minigbm/src/Makefile b/chromium/third_party/minigbm/src/Makefile index 17584444c41..32cbb572c46 100644 --- a/chromium/third_party/minigbm/src/Makefile +++ b/chromium/third_party/minigbm/src/Makefile @@ -21,7 +21,6 @@ ifdef DRV_EXYNOS endif ifdef DRV_I915 CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_intel) - LDLIBS += $(shell $(PKG_CONFIG) --libs libdrm_intel) endif ifdef DRV_ROCKCHIP CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_rockchip) diff --git a/chromium/third_party/minigbm/src/PRESUBMIT.cfg b/chromium/third_party/minigbm/src/PRESUBMIT.cfg new file mode 100644 index 00000000000..5dfbb4b7dfd --- /dev/null +++ b/chromium/third_party/minigbm/src/PRESUBMIT.cfg @@ -0,0 +1,12 @@ +# Copyright 2017 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. +[Hook Overrides] +stray_whitespace_check: false +long_line_check: false +cros_license_check: false +tab_check: false +bug_field_check: false +test_field_check: false +[Hook Scripts] +hook0 = ./presubmit.sh diff --git a/chromium/third_party/minigbm/src/amdgpu.c b/chromium/third_party/minigbm/src/amdgpu.c index 5dcfbeb0f9b..ee05009a36a 100644 --- a/chromium/third_party/minigbm/src/amdgpu.c +++ b/chromium/third_party/minigbm/src/amdgpu.c @@ -4,14 +4,14 @@ * found in the LICENSE file. */ #ifdef DRV_AMDGPU +#include <amdgpu.h> +#include <amdgpu_drm.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <xf86drm.h> -#include <amdgpu_drm.h> -#include <amdgpu.h> #include "addrinterface.h" #include "drv_priv.h" @@ -22,6 +22,7 @@ #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A #endif +// clang-format off #define mmCC_RB_BACKEND_DISABLE 0x263d #define mmGB_TILE_MODE0 0x2644 #define mmGB_MACROTILE_MODE0 0x2664 @@ -38,24 +39,16 @@ enum { FAMILY_PI, FAMILY_LAST, }; +// clang-format on -static struct supported_combination combos[5] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +const static uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +const static uint32_t texture_source_formats[] = { DRM_FORMAT_NV21, DRM_FORMAT_NV12 }; -static int amdgpu_set_metadata(int fd, uint32_t handle, - struct amdgpu_bo_metadata *info) +static int amdgpu_set_metadata(int fd, uint32_t handle, struct amdgpu_bo_metadata *info) { - struct drm_amdgpu_gem_metadata args = {0}; + struct drm_amdgpu_gem_metadata args = { 0 }; if (!info) return -EINVAL; @@ -73,18 +66,16 @@ static int amdgpu_set_metadata(int fd, uint32_t handle, memcpy(args.data.data, info->umd_metadata, info->size_metadata); } - return drmCommandWriteRead(fd, DRM_AMDGPU_GEM_METADATA, &args, - sizeof(args)); + return drmCommandWriteRead(fd, DRM_AMDGPU_GEM_METADATA, &args, sizeof(args)); } -static int amdgpu_read_mm_regs(int fd, unsigned dword_offset, - unsigned count, uint32_t instance, +static int amdgpu_read_mm_regs(int fd, unsigned dword_offset, unsigned count, uint32_t instance, uint32_t flags, uint32_t *values) { struct drm_amdgpu_info request; memset(&request, 0, sizeof(request)); - request.return_pointer = (uintptr_t) values; + request.return_pointer = (uintptr_t)values; request.return_size = count * sizeof(uint32_t); request.query = AMDGPU_INFO_READ_MMR_REG; request.read_mmr_reg.dword_offset = dword_offset; @@ -92,8 +83,7 @@ static int amdgpu_read_mm_regs(int fd, unsigned dword_offset, request.read_mmr_reg.instance = instance; request.read_mmr_reg.flags = flags; - return drmCommandWrite(fd, DRM_AMDGPU_INFO, &request, - sizeof(struct drm_amdgpu_info)); + return drmCommandWrite(fd, DRM_AMDGPU_INFO, &request, sizeof(struct drm_amdgpu_info)); } static int amdgpu_query_gpu(int fd, struct amdgpu_gpu_info *gpu_info) @@ -104,19 +94,16 @@ static int amdgpu_query_gpu(int fd, struct amdgpu_gpu_info *gpu_info) if (!gpu_info) return -EINVAL; - instance = AMDGPU_INFO_MMR_SH_INDEX_MASK << - AMDGPU_INFO_MMR_SH_INDEX_SHIFT; + instance = AMDGPU_INFO_MMR_SH_INDEX_MASK << AMDGPU_INFO_MMR_SH_INDEX_SHIFT; ret = amdgpu_read_mm_regs(fd, mmCC_RB_BACKEND_DISABLE, 1, instance, 0, &gpu_info->backend_disable[0]); if (ret) return ret; /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */ - gpu_info->backend_disable[0] = - (gpu_info->backend_disable[0] >> 16) & 0xff; + gpu_info->backend_disable[0] = (gpu_info->backend_disable[0] >> 16) & 0xff; - ret = amdgpu_read_mm_regs(fd, mmGB_TILE_MODE0, 32, 0xffffffff, 0, - gpu_info->gb_tile_mode); + ret = amdgpu_read_mm_regs(fd, mmGB_TILE_MODE0, 32, 0xffffffff, 0, gpu_info->gb_tile_mode); if (ret) return ret; @@ -125,13 +112,11 @@ static int amdgpu_query_gpu(int fd, struct amdgpu_gpu_info *gpu_info) if (ret) return ret; - ret = amdgpu_read_mm_regs(fd, mmGB_ADDR_CONFIG, 1, 0xffffffff, 0, - &gpu_info->gb_addr_cfg); + ret = amdgpu_read_mm_regs(fd, mmGB_ADDR_CONFIG, 1, 0xffffffff, 0, &gpu_info->gb_addr_cfg); if (ret) return ret; - ret = amdgpu_read_mm_regs(fd, mmMC_ARB_RAMCFG, 1, 0xffffffff, 0, - &gpu_info->mc_arb_ramcfg); + ret = amdgpu_read_mm_regs(fd, mmMC_ARB_RAMCFG, 1, 0xffffffff, 0, &gpu_info->mc_arb_ramcfg); if (ret) return ret; @@ -149,26 +134,27 @@ static ADDR_E_RETURNCODE ADDR_API free_sys_mem(const ADDR_FREESYSMEM_INPUT *in) return ADDR_OK; } -static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, - uint32_t height, uint32_t format, +static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height, uint32_t format, uint32_t usage, uint32_t *tiling_flags, ADDR_COMPUTE_SURFACE_INFO_OUTPUT *addr_out) { - ADDR_COMPUTE_SURFACE_INFO_INPUT addr_surf_info_in = {0}; - ADDR_TILEINFO addr_tile_info = {0}; - ADDR_TILEINFO addr_tile_info_out = {0}; + ADDR_COMPUTE_SURFACE_INFO_INPUT addr_surf_info_in = { 0 }; + ADDR_TILEINFO addr_tile_info = { 0 }; + ADDR_TILEINFO addr_tile_info_out = { 0 }; + uint32_t bits_per_pixel; addr_surf_info_in.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); /* Set the requested tiling mode. */ addr_surf_info_in.tileMode = ADDR_TM_2D_TILED_THIN1; - if (usage & (BO_USE_CURSOR | BO_USE_LINEAR)) + if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) addr_surf_info_in.tileMode = ADDR_TM_LINEAR_ALIGNED; - if (width <= 16 || height <= 16) + else if (width <= 16 || height <= 16) addr_surf_info_in.tileMode = ADDR_TM_1D_TILED_THIN1; + bits_per_pixel = drv_stride_from_format(format, 1, 0) * 8; /* Bits per pixel should be calculated from format*/ - addr_surf_info_in.bpp = drv_bpp_from_format(format, 0); + addr_surf_info_in.bpp = bits_per_pixel; addr_surf_info_in.numSamples = 1; addr_surf_info_in.width = width; addr_surf_info_in.height = height; @@ -188,13 +174,12 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, addr_out->size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); addr_out->pTileInfo = &addr_tile_info_out; - if (AddrComputeSurfaceInfo(addrlib, &addr_surf_info_in, - addr_out) != ADDR_OK) + if (AddrComputeSurfaceInfo(addrlib, &addr_surf_info_in, addr_out) != ADDR_OK) return -EINVAL; - ADDR_CONVERT_TILEINFOTOHW_INPUT s_in = {0}; - ADDR_CONVERT_TILEINFOTOHW_OUTPUT s_out = {0}; - ADDR_TILEINFO s_tile_hw_info_out = {0}; + ADDR_CONVERT_TILEINFOTOHW_INPUT s_in = { 0 }; + ADDR_CONVERT_TILEINFOTOHW_OUTPUT s_out = { 0 }; + ADDR_TILEINFO s_tile_hw_info_out = { 0 }; s_in.size = sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT); /* Convert from real value to HW value */ @@ -218,16 +203,13 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, /* LINEAR_ALIGNED */ *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); - *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, - drv_log_base2(addr_tile_info_out.bankWidth)); - *tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, - drv_log_base2(addr_tile_info_out.bankHeight)); - *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, - s_tile_hw_info_out.tileSplitBytes); + *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, drv_log_base2(addr_tile_info_out.bankWidth)); + *tiling_flags |= + AMDGPU_TILING_SET(BANK_HEIGHT, drv_log_base2(addr_tile_info_out.bankHeight)); + *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, s_tile_hw_info_out.tileSplitBytes); *tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, - drv_log_base2(addr_tile_info_out.macroAspectRatio)); - *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, - s_tile_hw_info_out.pipeConfig); + drv_log_base2(addr_tile_info_out.macroAspectRatio)); + *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, s_tile_hw_info_out.pipeConfig); *tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, s_tile_hw_info_out.banks); return 0; @@ -236,16 +218,16 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, static void *amdgpu_addrlib_init(int fd) { int ret; - ADDR_CREATE_INPUT addr_create_input = {0}; - ADDR_CREATE_OUTPUT addr_create_output = {0}; - ADDR_REGISTER_VALUE reg_value = {0}; - ADDR_CREATE_FLAGS create_flags = { {0} }; + ADDR_CREATE_INPUT addr_create_input = { 0 }; + ADDR_CREATE_OUTPUT addr_create_output = { 0 }; + ADDR_REGISTER_VALUE reg_value = { 0 }; + ADDR_CREATE_FLAGS create_flags = { { 0 } }; ADDR_E_RETURNCODE addr_ret; addr_create_input.size = sizeof(ADDR_CREATE_INPUT); addr_create_output.size = sizeof(ADDR_CREATE_OUTPUT); - struct amdgpu_gpu_info gpu_info = {0}; + struct amdgpu_gpu_info gpu_info = { 0 }; ret = amdgpu_query_gpu(fd, &gpu_info); @@ -260,11 +242,10 @@ static void *amdgpu_addrlib_init(int fd) reg_value.backendDisables = gpu_info.backend_disable[0]; reg_value.pTileConfig = gpu_info.gb_tile_mode; - reg_value.noOfEntries = sizeof(gpu_info.gb_tile_mode) - / sizeof(gpu_info.gb_tile_mode[0]); + reg_value.noOfEntries = sizeof(gpu_info.gb_tile_mode) / sizeof(gpu_info.gb_tile_mode[0]); reg_value.pMacroTileConfig = gpu_info.gb_macro_tile_mode; - reg_value.noOfMacroEntries = sizeof(gpu_info.gb_macro_tile_mode) - / sizeof(gpu_info.gb_macro_tile_mode[0]); + reg_value.noOfMacroEntries = + sizeof(gpu_info.gb_macro_tile_mode) / sizeof(gpu_info.gb_macro_tile_mode[0]); create_flags.value = 0; create_flags.useTileIndex = 1; @@ -289,7 +270,10 @@ static void *amdgpu_addrlib_init(int fd) static int amdgpu_init(struct driver *drv) { + int ret; void *addrlib; + struct format_metadata metadata; + uint32_t flags = BO_USE_RENDER_MASK; addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); if (!addrlib) @@ -297,8 +281,61 @@ static int amdgpu_init(struct driver *drv) drv->priv = addrlib; - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_SCANOUT); + + metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; + metadata.priority = 2; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); + + metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; + metadata.priority = 3; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + flags &= ~BO_USE_SW_WRITE_OFTEN; + flags &= ~BO_USE_SW_READ_OFTEN; + flags &= ~BO_USE_LINEAR; + + metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; + metadata.priority = 4; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); + + metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; + metadata.priority = 5; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + return ret; } static void amdgpu_close(struct driver *drv) @@ -307,55 +344,58 @@ static void amdgpu_close(struct driver *drv) drv->priv = NULL; } -static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) +static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t usage) { - void *addrlib = bo->drv->priv; + void *addrlib = bo->drv->priv; union drm_amdgpu_gem_create gem_create; - struct amdgpu_bo_metadata metadata = {0}; - ADDR_COMPUTE_SURFACE_INFO_OUTPUT addr_out = {0}; + struct amdgpu_bo_metadata metadata = { 0 }; + ADDR_COMPUTE_SURFACE_INFO_OUTPUT addr_out = { 0 }; uint32_t tiling_flags = 0; uint32_t gem_create_flags = 0; + size_t plane; int ret; - if (amdgpu_addrlib_compute(addrlib, width, - height, format, usage, - &tiling_flags, - &addr_out) < 0) - return -EINVAL; + if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { + drv_bo_from_format(bo, ALIGN(width, 64), height, format); + } else { + if (amdgpu_addrlib_compute(addrlib, width, height, format, usage, &tiling_flags, + &addr_out) < 0) + return -EINVAL; + + bo->tiling = tiling_flags; + /* RGB has 1 plane only */ + bo->offsets[0] = 0; + bo->total_size = bo->sizes[0] = addr_out.surfSize; + bo->strides[0] = addr_out.pixelPitch * DIV_ROUND_UP(addr_out.pixelBits, 8); + } - bo->tiling = tiling_flags; - bo->offsets[0] = 0; - bo->sizes[0] = addr_out.surfSize; - bo->strides[0] = addr_out.pixelPitch - * DIV_ROUND_UP(addr_out.pixelBits, 8); - if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_WRITE_RARELY | - BO_USE_SW_READ_RARELY)) + if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | + BO_USE_SW_WRITE_RARELY | BO_USE_SW_READ_RARELY)) gem_create_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; else gem_create_flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS; memset(&gem_create, 0, sizeof(gem_create)); - gem_create.in.bo_size = bo->sizes[0]; + + gem_create.in.bo_size = bo->total_size; gem_create.in.alignment = addr_out.baseAlign; /* Set the placement. */ gem_create.in.domains = AMDGPU_GEM_DOMAIN_VRAM; gem_create.in.domain_flags = gem_create_flags; - /* Allocate the buffer with the preferred heap. */ - ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, - &gem_create, sizeof(gem_create)); + ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, + sizeof(gem_create)); if (ret < 0) return ret; - bo->handles[0].u32 = gem_create.out.handle; - metadata.tiling_info = tiling_flags; - ret = amdgpu_set_metadata(drv_get_fd(bo->drv), - bo->handles[0].u32, &metadata); + for (plane = 0; plane < bo->num_planes; plane++) + bo->handles[plane].u32 = gem_create.out.handle; + + ret = amdgpu_set_metadata(drv_get_fd(bo->drv), bo->handles[0].u32, &metadata); return ret; } @@ -366,17 +406,27 @@ static void *amdgpu_bo_map(struct bo *bo, struct map_info *data, size_t plane) union drm_amdgpu_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); - gem_map.in.handle = bo->handles[0].u32; + gem_map.in.handle = bo->handles[plane].u32; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_map); if (ret) { fprintf(stderr, "drv: DRM_IOCTL_AMDGPU_GEM_MMAP failed\n"); return MAP_FAILED; } - data->length = bo->sizes[0]; + data->length = bo->total_size; - return mmap(0, bo->sizes[0], PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, gem_map.out.addr_ptr); + return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + gem_map.out.addr_ptr); +} + +static uint32_t amdgpu_resolve_format(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_FLEX_YCbCr_420_888: + return DRM_FORMAT_NV12; + default: + return format; + } } struct backend backend_amdgpu = { @@ -387,7 +437,7 @@ struct backend backend_amdgpu = { .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = amdgpu_bo_map, + .resolve_format = amdgpu_resolve_format, }; #endif - diff --git a/chromium/third_party/minigbm/src/cirrus.c b/chromium/third_party/minigbm/src/cirrus.c index f614e8ad08c..4f0e983538d 100644 --- a/chromium/third_party/minigbm/src/cirrus.c +++ b/chromium/third_party/minigbm/src/cirrus.c @@ -8,26 +8,21 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[3] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_RGB888, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +const static uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB888, + DRM_FORMAT_XRGB8888 }; static int cirrus_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_cirrus = -{ +struct backend backend_cirrus = { .name = "cirrus", .init = cirrus_init, .bo_create = drv_dumb_bo_create, diff --git a/chromium/third_party/minigbm/src/cros_gralloc/Makefile b/chromium/third_party/minigbm/src/cros_gralloc/Makefile index 27983553ef5..9c23e7b24c0 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/Makefile +++ b/chromium/third_party/minigbm/src/cros_gralloc/Makefile @@ -6,14 +6,20 @@ GRALLOC = gralloc.cros.so SRCS = $(wildcard *.cc) SRCS += $(wildcard ../*.c) + +SRCS += $(wildcard gralloc0/*.cc) + SOURCES = $(filter-out ../gbm%, $(SRCS)) +PKG_CONFIG ?= pkg-config VPATH = $(dir $(SOURCES)) +LIBDRM_CFLAGS := $(shell $(PKG_CONFIG) --cflags libdrm) +LIBDRM_LIBS := $(shell $(PKG_CONFIG) --libs libdrm) -CPPFLAGS += -Wall -fPIC -Werror -flto -CXXFLAGS += -std=c++11 +CPPFLAGS += -Wall -fPIC -Werror -flto $(LIBDRM_CFLAGS) +CXXFLAGS += -std=c++14 CFLAGS += -std=c99 -LIBS += -shared -lcutils -lhardware -ldrm +LIBS += -shared -lcutils -lhardware $(LIBDRM_LIBS) OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source)))) diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_alloc_device.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_alloc_device.cc deleted file mode 100644 index 97c8186f8c6..00000000000 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_alloc_device.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2016 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 "cros_gralloc.h" - -static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv, - int width, int height, - int format, int usage) -{ - int32_t supported; - uint64_t drv_usage; - uint32_t drv_format; - struct cros_gralloc_bo *bo; - - drv_format = cros_gralloc_convert_format(format); - drv_format = drv_resolve_format(drv, drv_format); - drv_usage = cros_gralloc_convert_flags(usage); - - supported = drv_is_combination_supported(drv, drv_format, drv_usage, - DRM_FORMAT_MOD_NONE); - - if (!supported && (drv_usage & BO_USE_SCANOUT)) { - drv_usage &= ~BO_USE_SCANOUT; - supported = drv_is_combination_supported(drv, drv_format, - drv_usage, - DRM_FORMAT_MOD_NONE); - } - - if (!supported && (drv_usage & BO_USE_RENDERING) && - (drv_usage && (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN))) { - drv_usage &= ~BO_USE_RENDERING; - supported = drv_is_combination_supported(drv, drv_format, - drv_usage, - DRM_FORMAT_MOD_NONE); - } - - if (!supported) { - cros_gralloc_error("Unsupported combination -- HAL format: %u, " - "HAL flags: %u, drv_format: %u, " - "drv_flags: %llu", format, usage, - drv_format, drv_usage); - return NULL; - } - - bo = new cros_gralloc_bo(); - memset(bo, 0, sizeof(*bo)); - - bo->bo = drv_bo_create(drv, width, height, drv_format, drv_usage); - if (!bo->bo) { - delete bo; - cros_gralloc_error("Failed to create bo."); - return NULL; - } - - /* - * If there is a desire for more than one kernel buffer, this can be - * removed once the ArcCodec and Wayland service have the ability to - * send more than one fd. GL/Vulkan drivers may also have to modified. - */ - if (drv_num_buffers_per_bo(bo->bo) != 1) { - drv_bo_destroy(bo->bo); - delete bo; - cros_gralloc_error("Can only support one buffer per bo."); - return NULL; - } - - bo->refcount = 1; - - return bo; -} - -static struct cros_gralloc_handle *cros_gralloc_handle_from_bo(struct bo *bo) -{ - uint64_t mod; - size_t num_planes; - struct cros_gralloc_handle *hnd; - - hnd = new cros_gralloc_handle(); - memset(hnd, 0, sizeof(*hnd)); - - num_planes = drv_bo_get_num_planes(bo); - - hnd->base.version = sizeof(hnd->base); - hnd->base.numFds = num_planes; - hnd->base.numInts = num_ints_handle() - num_planes; - - for (size_t p = 0; p < num_planes; p++) { - hnd->fds[p] = drv_bo_get_plane_fd(bo, p); - hnd->strides[p] = drv_bo_get_plane_stride(bo, p); - hnd->offsets[p] = drv_bo_get_plane_offset(bo, p); - hnd->sizes[p] = drv_bo_get_plane_size(bo, p); - - mod = drv_bo_get_plane_format_modifier(bo, p); - hnd->format_modifiers[p] = static_cast<uint32_t>(mod >> 32); - hnd->format_modifiers[p+1] = static_cast<uint32_t>(mod); - } - - hnd->width = drv_bo_get_width(bo); - hnd->height = drv_bo_get_height(bo); - hnd->format = drv_bo_get_format(bo); - - hnd->magic = cros_gralloc_magic(); - - hnd->pixel_stride = hnd->strides[0]; - hnd->pixel_stride /= drv_stride_from_format(hnd->format, 1, 0); - - return hnd; -} - -static int cros_gralloc_alloc(alloc_device_t *dev, int w, int h, int format, - int usage, buffer_handle_t *handle, int *stride) -{ - auto mod = (struct cros_gralloc_module *) dev->common.module; - std::lock_guard<std::mutex> lock(mod->mutex); - - auto bo = cros_gralloc_bo_create(mod->drv, w, h, format, usage); - if (!bo) - return CROS_GRALLOC_ERROR_NO_RESOURCES; - - auto hnd = cros_gralloc_handle_from_bo(bo->bo); - hnd->droid_format = static_cast<int32_t>(format); - hnd->usage = static_cast<int32_t>(usage); - - mod->handles[hnd].registrations = 0; - mod->handles[hnd].bo = bo; - bo->hnd = hnd; - - mod->buffers[drv_bo_get_plane_handle(bo->bo, 0).u32] = bo; - - *stride = static_cast<int>(hnd->pixel_stride); - *handle = &hnd->base; - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_free(alloc_device_t *dev, buffer_handle_t handle) -{ - struct cros_gralloc_bo *bo; - auto hnd = (struct cros_gralloc_handle *) handle; - auto mod = (struct cros_gralloc_module *) dev->common.module; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (mod->handles[hnd].registrations > 0) { - cros_gralloc_error("Deallocating before unregistering."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - return cros_gralloc_decrement_reference_count(mod, bo); -} - -static int cros_gralloc_close(struct hw_device_t *dev) -{ - auto mod = (struct cros_gralloc_module *) dev->module; - auto alloc = (struct alloc_device_t *) dev; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (mod->drv) { - drv_destroy(mod->drv); - mod->drv = NULL; - } - - mod->buffers.clear(); - mod->handles.clear(); - - delete alloc; - - return CROS_GRALLOC_ERROR_NONE; -} - -int cros_gralloc_open(const struct hw_module_t *mod, const char *name, - struct hw_device_t **dev) -{ - auto module = (struct cros_gralloc_module *) mod; - std::lock_guard<std::mutex> lock(module->mutex); - - if (module->drv) - return CROS_GRALLOC_ERROR_NONE; - - if (strcmp(name, GRALLOC_HARDWARE_GPU0)) { - cros_gralloc_error("Incorrect device name - %s.", name); - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - - if (cros_gralloc_rendernode_open(&module->drv)) { - cros_gralloc_error("Failed to open render node."); - return CROS_GRALLOC_ERROR_NO_RESOURCES; - } - - auto alloc = new alloc_device_t(); - memset(alloc, 0, sizeof(*alloc)); - - alloc->alloc = cros_gralloc_alloc; - alloc->free = cros_gralloc_free; - alloc->common.tag = HARDWARE_DEVICE_TAG; - alloc->common.version = 0; - alloc->common.module = (hw_module_t*) mod; - alloc->common.close = cros_gralloc_close; - - *dev = &alloc->common; - - return CROS_GRALLOC_ERROR_NONE; -} diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc.h deleted file mode 100644 index 6cd98dd2f48..00000000000 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016 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. - */ - -#ifndef GBM_GRALLOC_H -#define GBM_GRALLOC_H - -#include "cros_gralloc_helpers.h" - -#include <mutex> -#include <unordered_set> -#include <unordered_map> - -struct cros_gralloc_bo { - struct bo *bo; - int32_t refcount; - struct cros_gralloc_handle *hnd; - void *map_data; -}; - -struct handle_info { - cros_gralloc_bo *bo; - int32_t registrations; -}; - -struct cros_gralloc_module { - gralloc_module_t base; - struct driver *drv; - std::mutex mutex; - std::unordered_map<cros_gralloc_handle*, handle_info> handles; - std::unordered_map<uint32_t, cros_gralloc_bo*> buffers; -}; - -int cros_gralloc_open(const struct hw_module_t *mod, const char *name, - struct hw_device_t **dev); - -int cros_gralloc_validate_reference(struct cros_gralloc_module *mod, - struct cros_gralloc_handle *hnd, - struct cros_gralloc_bo **obj); - -int cros_gralloc_decrement_reference_count(struct cros_gralloc_module *mod, - struct cros_gralloc_bo *obj); - -#endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc new file mode 100644 index 00000000000..1ef7278e1fa --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc @@ -0,0 +1,97 @@ +/* + * Copyright 2017 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 "cros_gralloc_buffer.h" + +#include <assert.h> +#include <sys/mman.h> + +cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquirebo_, + struct cros_gralloc_handle *acquire_handle) + : id_(id), bo_(acquirebo_), hnd_(acquire_handle), refcount_(1), lockcount_(0) +{ + assert(bo_); + num_planes_ = drv_bo_get_num_planes(bo_); + for (uint32_t plane = 0; plane < num_planes_; plane++) + lock_data_[plane] = nullptr; +} + +cros_gralloc_buffer::~cros_gralloc_buffer() +{ + drv_bo_destroy(bo_); + if (hnd_) { + native_handle_close(&hnd_->base); + delete hnd_; + } +} + +uint32_t cros_gralloc_buffer::get_id() const +{ + return id_; +} + +int32_t cros_gralloc_buffer::increase_refcount() +{ + return ++refcount_; +} + +int32_t cros_gralloc_buffer::decrease_refcount() +{ + assert(refcount_ > 0); + return --refcount_; +} + +int32_t cros_gralloc_buffer::lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES]) +{ + /* + * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so + * just use the first kernel buffer. + */ + if (drv_num_buffers_per_bo(bo_) != 1) { + cros_gralloc_error("Can only support one buffer per bo."); + return CROS_GRALLOC_ERROR_NO_RESOURCES; + } + + if (flags) { + void *vaddr; + if (lock_data_[0]) { + vaddr = lock_data_[0]->addr; + } else { + vaddr = drv_bo_map(bo_, 0, 0, drv_bo_get_width(bo_), drv_bo_get_height(bo_), + 0, &lock_data_[0], 0); + } + + if (vaddr == MAP_FAILED) { + cros_gralloc_error("Mapping failed."); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + addr[0] = static_cast<uint8_t *>(vaddr); + } + + for (uint32_t plane = 0; plane < num_planes_; plane++) + addr[plane] = addr[0] + drv_bo_get_plane_offset(bo_, plane); + + lockcount_++; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t cros_gralloc_buffer::unlock() +{ + if (lockcount_ <= 0) { + cros_gralloc_error("Buffer was not locked."); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + if (!--lockcount_) { + if (lock_data_[0]) { + drv_bo_unmap(bo_, lock_data_[0]); + lock_data_[0] = nullptr; + } + } + + return CROS_GRALLOC_ERROR_NONE; +} diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h new file mode 100644 index 00000000000..673ff9d8f0b --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 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. + */ + +#ifndef CROS_GRALLOC_BUFFER_H +#define CROS_GRALLOC_BUFFER_H + +#include "../drv.h" +#include "cros_gralloc_helpers.h" + +class cros_gralloc_buffer +{ + public: + cros_gralloc_buffer(uint32_t id, struct bo *acquirebo_, + struct cros_gralloc_handle *acquire_handle); + ~cros_gralloc_buffer(); + + uint32_t get_id() const; + + /* The new reference count is returned by both these functions. */ + int32_t increase_refcount(); + int32_t decrease_refcount(); + + int32_t lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES]); + int32_t unlock(); + + private: + cros_gralloc_buffer(cros_gralloc_buffer const &); + cros_gralloc_buffer operator=(cros_gralloc_buffer const &); + + uint32_t id_; + struct bo *bo_; + struct cros_gralloc_handle *hnd_; + + int32_t refcount_; + int32_t lockcount_; + uint32_t num_planes_; + + struct map_info *lock_data_[DRV_MAX_PLANES]; +}; + +#endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc new file mode 100644 index 00000000000..603e96d5a7d --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc @@ -0,0 +1,304 @@ +/* + * Copyright 2017 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 "cros_gralloc_driver.h" +#include "../util.h" + +#include <cstdlib> +#include <fcntl.h> +#include <xf86drm.h> + +cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr) +{ +} + +cros_gralloc_driver::~cros_gralloc_driver() +{ + buffers_.clear(); + handles_.clear(); + + if (drv_) { + drv_destroy(drv_); + drv_ = nullptr; + } +} + +int32_t cros_gralloc_driver::init() +{ + /* + * Create a driver from rendernode while filtering out + * the specified undesired driver. + * + * TODO(gsingh): Enable render nodes on udl/evdi. + */ + + int fd; + drmVersionPtr version; + char const *str = "%s/renderD%d"; + const char *undesired[2] = { "vgem", nullptr }; + uint32_t num_nodes = 63; + uint32_t min_node = 128; + uint32_t max_node = (min_node + num_nodes); + + for (uint32_t i = 0; i < ARRAY_SIZE(undesired); i++) { + for (uint32_t j = min_node; j < max_node; j++) { + char *node; + if (asprintf(&node, str, DRM_DIR_NAME, j) < 0) + continue; + + fd = open(node, O_RDWR, 0); + free(node); + + if (fd < 0) + continue; + + version = drmGetVersion(fd); + if (!version) + continue; + + if (undesired[i] && !strcmp(version->name, undesired[i])) { + drmFreeVersion(version); + continue; + } + + drmFreeVersion(version); + drv_ = drv_create(fd); + if (drv_) + return CROS_GRALLOC_ERROR_NONE; + } + } + + return CROS_GRALLOC_ERROR_NO_RESOURCES; +} + +bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor) +{ + struct combination *combo; + combo = drv_get_combination(drv_, drv_resolve_format(drv_, descriptor->drm_format), + descriptor->drv_usage); + return (combo != nullptr); +} + +int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor, + buffer_handle_t *out_handle) +{ + uint32_t id; + uint64_t mod; + size_t num_planes; + + struct bo *bo; + struct cros_gralloc_handle *hnd; + + bo = drv_bo_create(drv_, descriptor->width, descriptor->height, + drv_resolve_format(drv_, descriptor->drm_format), descriptor->drv_usage); + if (!bo) { + cros_gralloc_error("Failed to create bo."); + return CROS_GRALLOC_ERROR_NO_RESOURCES; + } + + /* + * If there is a desire for more than one kernel buffer, this can be + * removed once the ArcCodec and Wayland service have the ability to + * send more than one fd. GL/Vulkan drivers may also have to modified. + */ + if (drv_num_buffers_per_bo(bo) != 1) { + drv_bo_destroy(bo); + cros_gralloc_error("Can only support one buffer per bo."); + return CROS_GRALLOC_ERROR_NO_RESOURCES; + } + + hnd = new cros_gralloc_handle(); + num_planes = drv_bo_get_num_planes(bo); + + hnd->base.version = sizeof(hnd->base); + hnd->base.numFds = num_planes; + hnd->base.numInts = handle_data_size - num_planes; + + for (size_t plane = 0; plane < num_planes; plane++) { + hnd->fds[plane] = drv_bo_get_plane_fd(bo, plane); + hnd->strides[plane] = drv_bo_get_plane_stride(bo, plane); + hnd->offsets[plane] = drv_bo_get_plane_offset(bo, plane); + hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane); + + mod = drv_bo_get_plane_format_modifier(bo, plane); + hnd->format_modifiers[2 * plane] = static_cast<uint32_t>(mod >> 32); + hnd->format_modifiers[2 * plane + 1] = static_cast<uint32_t>(mod); + } + + hnd->width = drv_bo_get_width(bo); + hnd->height = drv_bo_get_height(bo); + hnd->format = drv_bo_get_format(bo); + hnd->pixel_stride = drv_bo_get_stride_in_pixels(bo); + hnd->magic = cros_gralloc_magic; + hnd->droid_format = descriptor->droid_format; + hnd->usage = descriptor->producer_usage; + + id = drv_bo_get_plane_handle(bo, 0).u32; + auto buffer = new cros_gralloc_buffer(id, bo, hnd); + + std::lock_guard<std::mutex> lock(mutex_); + buffers_.emplace(id, buffer); + handles_.emplace(hnd, std::make_pair(buffer, 1)); + *out_handle = &hnd->base; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t cros_gralloc_driver::retain(buffer_handle_t handle) +{ + uint32_t id; + std::lock_guard<std::mutex> lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + auto buffer = get_buffer(hnd); + if (buffer) { + handles_[hnd].second++; + buffer->increase_refcount(); + return CROS_GRALLOC_ERROR_NONE; + } + + if (drmPrimeFDToHandle(drv_get_fd(drv_), hnd->fds[0], &id)) { + cros_gralloc_error("drmPrimeFDToHandle failed."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (buffers_.count(id)) { + buffer = buffers_[id]; + buffer->increase_refcount(); + } else { + struct bo *bo; + struct drv_import_fd_data data; + data.format = hnd->format; + data.width = hnd->width; + data.height = hnd->height; + + memcpy(data.fds, hnd->fds, sizeof(data.fds)); + memcpy(data.strides, hnd->strides, sizeof(data.strides)); + memcpy(data.offsets, hnd->offsets, sizeof(data.offsets)); + memcpy(data.sizes, hnd->sizes, sizeof(data.sizes)); + for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) { + data.format_modifiers[plane] = + static_cast<uint64_t>(hnd->format_modifiers[2 * plane]) << 32; + data.format_modifiers[plane] |= hnd->format_modifiers[2 * plane + 1]; + } + + bo = drv_bo_import(drv_, &data); + if (!bo) + return CROS_GRALLOC_ERROR_NO_RESOURCES; + + id = drv_bo_get_plane_handle(bo, 0).u32; + + buffer = new cros_gralloc_buffer(id, bo, nullptr); + buffers_.emplace(id, buffer); + } + + handles_.emplace(hnd, std::make_pair(buffer, 1)); + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t cros_gralloc_driver::release(buffer_handle_t handle) +{ + std::lock_guard<std::mutex> lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + cros_gralloc_error("Invalid Reference."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (!--handles_[hnd].second) + handles_.erase(hnd); + + if (buffer->decrease_refcount() == 0) { + buffers_.erase(buffer->get_id()); + delete buffer; + } + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags, + uint8_t *addr[DRV_MAX_PLANES]) +{ + std::lock_guard<std::mutex> lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + cros_gralloc_error("Invalid Reference."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (acquire_fence >= 0) { + cros_gralloc_error("Sync wait not yet supported."); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + return buffer->lock(flags, addr); +} + +int32_t cros_gralloc_driver::unlock(buffer_handle_t handle) +{ + std::lock_guard<std::mutex> lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + cros_gralloc_error("Invalid Reference."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + return buffer->unlock(); +} + +int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store) +{ + std::lock_guard<std::mutex> lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + cros_gralloc_error("Invalid Reference."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *out_store = static_cast<uint64_t>(buffer->get_id()); + return CROS_GRALLOC_ERROR_NONE; +} + +cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) +{ + /* Assumes driver mutex is held. */ + if (handles_.count(hnd)) + return handles_[hnd].first; + + return nullptr; +} diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h new file mode 100644 index 00000000000..7b3b668f2cb --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 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. + */ + +#ifndef CROS_GRALLOC_DRIVER_H +#define CROS_GRALLOC_DRIVER_H + +#include "cros_gralloc_buffer.h" + +#include <mutex> +#include <unordered_map> + +class cros_gralloc_driver +{ + public: + cros_gralloc_driver(); + ~cros_gralloc_driver(); + + int32_t init(); + bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor); + int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor, + buffer_handle_t *out_handle); + + int32_t retain(buffer_handle_t handle); + int32_t release(buffer_handle_t handle); + + int32_t lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags, + uint8_t *addr[DRV_MAX_PLANES]); + int32_t unlock(buffer_handle_t handle); + + int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store); + + private: + cros_gralloc_driver(cros_gralloc_driver const &); + cros_gralloc_driver operator=(cros_gralloc_driver const &); + cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd); + + struct driver *drv_; + std::mutex mutex_; + std::unordered_map<uint32_t, cros_gralloc_buffer *> buffers_; + std::unordered_map<cros_gralloc_handle_t, std::pair<cros_gralloc_buffer *, int32_t>> + handles_; +}; + +#endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h index 63b9da9f909..e549675fc41 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h @@ -7,8 +7,8 @@ #ifndef CROS_GRALLOC_HANDLE_H #define CROS_GRALLOC_HANDLE_H -#include <cutils/native_handle.h> #include <cstdint> +#include <cutils/native_handle.h> #define DRV_MAX_PLANES 4 @@ -26,11 +26,13 @@ struct cros_gralloc_handle { uint32_t format_modifiers[2 * DRV_MAX_PLANES]; uint32_t width; uint32_t height; - uint32_t format; /* DRM format */ + uint32_t format; /* DRM format */ uint32_t magic; uint32_t pixel_stride; int32_t droid_format; - int32_t usage; /* Android usage. */ + int32_t usage; /* Android usage. */ }; +typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; + #endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.cc index afb1a96dcef..f0b667d2bc1 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.cc +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.cc @@ -8,53 +8,6 @@ #include <cstdlib> #include <cutils/log.h> -#include <fcntl.h> -#include <xf86drm.h> - -uint64_t cros_gralloc_convert_flags(int flags) -{ - uint64_t usage = BO_USE_NONE; - - if (flags & GRALLOC_USAGE_CURSOR) - usage |= BO_USE_NONE; - if ((flags & sw_read()) == GRALLOC_USAGE_SW_READ_RARELY) - usage |= BO_USE_SW_READ_RARELY; - if ((flags & sw_read()) == GRALLOC_USAGE_SW_READ_OFTEN) - usage |= BO_USE_SW_READ_OFTEN; - if ((flags & sw_write()) == GRALLOC_USAGE_SW_WRITE_RARELY) - usage |= BO_USE_SW_WRITE_RARELY; - if ((flags & sw_write()) == GRALLOC_USAGE_SW_WRITE_OFTEN) - usage |= BO_USE_SW_WRITE_OFTEN; - if (flags & GRALLOC_USAGE_HW_TEXTURE) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_RENDER) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_2D) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_COMPOSER) - /* HWC wants to use display hardware, but can defer to OpenGL. */ - usage |= BO_USE_SCANOUT | BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_FB) - usage |= BO_USE_SCANOUT | BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_EXTERNAL_DISP) - /* We're ignoring this flag until we decide what to with display link */ - usage |= BO_USE_NONE; - if (flags & GRALLOC_USAGE_PROTECTED) - usage |= BO_USE_PROTECTED; - if (flags & GRALLOC_USAGE_HW_VIDEO_ENCODER) - /*HACK: See b/30054495 */ - usage |= BO_USE_SW_READ_OFTEN; - if (flags & GRALLOC_USAGE_HW_CAMERA_WRITE) - usage |= BO_USE_HW_CAMERA_WRITE; - if (flags & GRALLOC_USAGE_HW_CAMERA_READ) - usage |= BO_USE_HW_CAMERA_READ; - if (flags & GRALLOC_USAGE_HW_CAMERA_ZSL) - usage |= BO_USE_HW_CAMERA_ZSL; - if (flags & GRALLOC_USAGE_RENDERSCRIPT) - usage |= BO_USE_RENDERSCRIPT; - - return usage; -} uint32_t cros_gralloc_convert_format(int format) { @@ -79,82 +32,29 @@ uint32_t cros_gralloc_convert_format(int format) case HAL_PIXEL_FORMAT_YCbCr_420_888: return DRM_FORMAT_FLEX_YCbCr_420_888; case HAL_PIXEL_FORMAT_YV12: - return DRM_FORMAT_YVU420; - } - - return DRM_FORMAT_NONE; -} - -static int32_t cros_gralloc_query_rendernode(struct driver **drv, - const char *undesired) -{ + return DRM_FORMAT_YVU420_ANDROID; /* - * Create a driver from rendernode while filtering out - * the specified undesired driver. - * - * TODO(gsingh): Enable render nodes on udl/evdi. + * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers + * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width + * equal to their size in bytes. */ - - int fd; - drmVersionPtr version; - char const *str = "%s/renderD%d"; - int32_t num_nodes = 63; - int32_t min_node = 128; - int32_t max_node = (min_node + num_nodes); - - for (int i = min_node; i < max_node; i++) { - char *node; - - if (asprintf(&node, str, DRM_DIR_NAME, i) < 0) - continue; - - fd = open(node, O_RDWR, 0); - free(node); - - if (fd < 0) - continue; - - version = drmGetVersion(fd); - if (!version) - continue; - - if (undesired && !strcmp(version->name, undesired)) { - drmFreeVersion(version); - continue; - } - - drmFreeVersion(version); - *drv = drv_create(fd); - - if (*drv) - return CROS_GRALLOC_ERROR_NONE; + case HAL_PIXEL_FORMAT_BLOB: + return DRM_FORMAT_R8; } - return CROS_GRALLOC_ERROR_NO_RESOURCES; -} - -int32_t cros_gralloc_rendernode_open(struct driver **drv) -{ - int32_t ret; - ret = cros_gralloc_query_rendernode(drv, "vgem"); - - /* Allow vgem driver if no hardware is found. */ - if (ret) - ret = cros_gralloc_query_rendernode(drv, NULL); - - return ret; + return DRM_FORMAT_NONE; } -int32_t cros_gralloc_validate_handle(struct cros_gralloc_handle *hnd) +cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) { - if (!hnd || hnd->magic != cros_gralloc_magic()) - return CROS_GRALLOC_ERROR_BAD_HANDLE; + auto hnd = reinterpret_cast<cros_gralloc_handle_t>(handle); + if (!hnd || hnd->magic != cros_gralloc_magic) + return nullptr; - return CROS_GRALLOC_ERROR_NONE; + return hnd; } -void cros_gralloc_log(const char *prefix, const char *file, int line, - const char *format, ...) +void cros_gralloc_log(const char *prefix, const char *file, int line, const char *format, ...) { char buf[50]; snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, basename(file), line); diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.h index 7ba3a9a7033..f198dd9668d 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_helpers.h @@ -9,79 +9,25 @@ #include "../drv.h" #include "cros_gralloc_handle.h" +#include "cros_gralloc_types.h" -#include <hardware/gralloc.h> #include <system/graphics.h> +#include <system/window.h> -/* Use these error codes derived from gralloc1 to make transition easier when - * it happens - */ -typedef enum { - CROS_GRALLOC_ERROR_NONE = 0, - CROS_GRALLOC_ERROR_BAD_DESCRIPTOR = 1, - CROS_GRALLOC_ERROR_BAD_HANDLE = 2, - CROS_GRALLOC_ERROR_BAD_VALUE = 3, - CROS_GRALLOC_ERROR_NOT_SHARED = 4, - CROS_GRALLOC_ERROR_NO_RESOURCES = 5, - CROS_GRALLOC_ERROR_UNDEFINED = 6, - CROS_GRALLOC_ERROR_UNSUPPORTED = 7, -} cros_gralloc_error_t; - -/* This enumeration must match the one in <gralloc_drm.h>. - * The functions supported by this gralloc's temporary private API are listed - * below. Use of these functions is highly discouraged and should only be - * reserved for cases where no alternative to get same information (such as - * querying ANativeWindow) exists. - */ -enum { - GRALLOC_DRM_GET_STRIDE, - GRALLOC_DRM_GET_FORMAT, - GRALLOC_DRM_GET_DIMENSIONS, - GRALLOC_DRM_GET_BACKING_STORE, -}; - -constexpr uint32_t cros_gralloc_magic(void) -{ - return 0xABCDDCBA; -} - -constexpr uint32_t num_ints_handle() -{ - return ((sizeof(struct cros_gralloc_handle)) / sizeof(int)); -} - -constexpr uint32_t sw_access(void) -{ - return GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK; -} - -constexpr uint32_t sw_read(void) -{ - return GRALLOC_USAGE_SW_READ_MASK; -} - -constexpr uint32_t sw_write(void) -{ - return GRALLOC_USAGE_SW_WRITE_MASK; -} - -uint64_t cros_gralloc_convert_flags(int flags); - -uint32_t cros_gralloc_convert_format(int format); +constexpr uint32_t cros_gralloc_magic = 0xABCDDCBA; +constexpr uint32_t handle_data_size = + ((sizeof(struct cros_gralloc_handle) - offsetof(cros_gralloc_handle, fds[0])) / sizeof(int)); -int32_t cros_gralloc_rendernode_open(struct driver **drv); +uint32_t cros_gralloc_convert_format(int32_t format); -int32_t cros_gralloc_validate_handle(struct cros_gralloc_handle *hnd); +cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); -/* Logging code adapted from bsdrm */ -__attribute__((format(printf, 4, 5))) -void cros_gralloc_log(const char *prefix, const char *file, int line, - const char *format, ...); +__attribute__((format(printf, 4, 5))) void cros_gralloc_log(const char *prefix, const char *file, + int line, const char *format, ...); -#define cros_gralloc_error(...) \ - do { \ - cros_gralloc_log("CROS_GRALLOC_ERROR", __FILE__, \ - __LINE__, __VA_ARGS__); \ +#define cros_gralloc_error(...) \ + do { \ + cros_gralloc_log("CROS_GRALLOC_ERROR", __FILE__, __LINE__, __VA_ARGS__); \ } while (0) #endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_module.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_module.cc deleted file mode 100644 index 470648c322b..00000000000 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_module.cc +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright 2016 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 "cros_gralloc.h" - -#include <sys/mman.h> -#include <xf86drm.h> - -int cros_gralloc_validate_reference(struct cros_gralloc_module *mod, - struct cros_gralloc_handle *hnd, - struct cros_gralloc_bo **bo) -{ - if (!mod->handles.count(hnd)) - return CROS_GRALLOC_ERROR_BAD_HANDLE; - - *bo = mod->handles[hnd].bo; - return CROS_GRALLOC_ERROR_NONE; -} - -int cros_gralloc_decrement_reference_count(struct cros_gralloc_module *mod, - struct cros_gralloc_bo *bo) -{ - if (bo->refcount <= 0) { - cros_gralloc_error("The reference count is <= 0."); - assert(0); - } - - if (!--bo->refcount) { - mod->buffers.erase(drv_bo_get_plane_handle(bo->bo, 0).u32); - drv_bo_destroy(bo->bo); - - if (bo->hnd) { - mod->handles.erase(bo->hnd); - native_handle_close(&bo->hnd->base); - delete bo->hnd; - } - - delete bo; - } - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_register_buffer(struct gralloc_module_t const* module, - buffer_handle_t handle) -{ - uint32_t id; - struct cros_gralloc_bo *bo; - auto hnd = (struct cros_gralloc_handle *) handle; - auto mod = (struct cros_gralloc_module *) module; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (!mod->drv) { - if (cros_gralloc_rendernode_open(&mod->drv)) { - cros_gralloc_error("Failed to open render node."); - return CROS_GRALLOC_ERROR_NO_RESOURCES; - } - } - - if (!cros_gralloc_validate_reference(mod, hnd, &bo)) { - bo->refcount++; - mod->handles[hnd].registrations++; - return CROS_GRALLOC_ERROR_NONE; - } - - if (drmPrimeFDToHandle(drv_get_fd(mod->drv), hnd->fds[0], &id)) { - cros_gralloc_error("drmPrimeFDToHandle failed."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (mod->buffers.count(id)) { - bo = mod->buffers[id]; - bo->refcount++; - } else { - struct drv_import_fd_data data; - size_t num_planes = drv_num_planes_from_format(hnd->format); - - data.format = hnd->format; - data.width = hnd->width; - data.height = hnd->height; - for (size_t p = 0; p < num_planes; p++) { - data.fds[p] = hnd->fds[p]; - data.strides[p] = hnd->strides[p]; - data.offsets[p] = hnd->offsets[p]; - data.sizes[p] = hnd->sizes[p]; - data.format_modifiers[p] = static_cast<uint64_t> - (hnd->format_modifiers[p]) << 32; - data.format_modifiers[p] |= hnd->format_modifiers[p+1]; - } - - bo = new cros_gralloc_bo(); - - bo->bo = drv_bo_import(mod->drv, &data); - if (!bo->bo) { - delete bo; - return CROS_GRALLOC_ERROR_NO_RESOURCES; - } - - id = drv_bo_get_plane_handle(bo->bo, 0).u32; - mod->buffers[id] = bo; - - bo->refcount = 1; - } - - mod->handles[hnd].bo = bo; - mod->handles[hnd].registrations = 1; - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_unregister_buffer(struct gralloc_module_t const* module, - buffer_handle_t handle) -{ - struct cros_gralloc_bo *bo; - auto hnd = (struct cros_gralloc_handle *) handle; - auto mod = (struct cros_gralloc_module *) module; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (mod->handles[hnd].registrations <= 0) { - cros_gralloc_error("Handle not registered."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - mod->handles[hnd].registrations--; - - if (!mod->handles[hnd].registrations) - mod->handles.erase(hnd); - - return cros_gralloc_decrement_reference_count(mod, bo); -} - -static int cros_gralloc_lock(struct gralloc_module_t const* module, - buffer_handle_t handle, int usage, int l, int t, - int w, int h, void** vaddr) -{ - struct cros_gralloc_bo *bo; - auto mod = (struct cros_gralloc_module *) module; - auto hnd = (struct cros_gralloc_handle *) handle; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) { - cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not " - "compatible."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (sw_access() & usage) { - *vaddr = drv_bo_map(bo->bo, 0, 0, drv_bo_get_width(bo->bo), - drv_bo_get_height(bo->bo), 0, &bo->map_data, - 0); - - if (*vaddr == MAP_FAILED) { - cros_gralloc_error("Mapping failed."); - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - } - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_unlock(struct gralloc_module_t const* module, - buffer_handle_t handle) -{ - struct cros_gralloc_bo *bo; - auto hnd = (struct cros_gralloc_handle *) handle; - auto mod = (struct cros_gralloc_module *) module; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (bo->map_data) - drv_bo_unmap(bo->bo, bo->map_data); - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_perform(struct gralloc_module_t const* module, - int op, ... ) -{ - va_list args; - struct cros_gralloc_bo *bo; - int32_t *out_format; - uint64_t *out_store; - buffer_handle_t handle; - uint32_t *out_width, *out_height, *out_stride; - auto mod = (struct cros_gralloc_module *) module; - std::lock_guard<std::mutex> lock(mod->mutex); - - switch (op) { - case GRALLOC_DRM_GET_STRIDE: - case GRALLOC_DRM_GET_FORMAT: - case GRALLOC_DRM_GET_DIMENSIONS: - case GRALLOC_DRM_GET_BACKING_STORE: - break; - default: - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - - va_start(args, op); - handle = va_arg(args, buffer_handle_t); - auto hnd = (struct cros_gralloc_handle *) handle; - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - switch (op) { - case GRALLOC_DRM_GET_STRIDE: - out_stride = va_arg(args, uint32_t *); - *out_stride = hnd->pixel_stride; - break; - case GRALLOC_DRM_GET_FORMAT: - out_format = va_arg(args, int32_t *); - *out_format = hnd->droid_format; - break; - case GRALLOC_DRM_GET_DIMENSIONS: - out_width = va_arg(args, uint32_t *); - out_height = va_arg(args, uint32_t *); - *out_width = hnd->width; - *out_height = hnd->height; - break; - case GRALLOC_DRM_GET_BACKING_STORE: - out_store = va_arg(args, uint64_t *); - *out_store = drv_bo_get_plane_handle(bo->bo, 0).u64; - break; - default: - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - - va_end(args); - - return CROS_GRALLOC_ERROR_NONE; -} - -static int cros_gralloc_lock_ycbcr(struct gralloc_module_t const* module, - buffer_handle_t handle, int usage, int l, - int t, int w, int h, - struct android_ycbcr *ycbcr) -{ - uint8_t *addr = NULL; - size_t offsets[DRV_MAX_PLANES]; - struct cros_gralloc_bo *bo; - auto hnd = (struct cros_gralloc_handle *) handle; - auto mod = (struct cros_gralloc_module *) module; - std::lock_guard<std::mutex> lock(mod->mutex); - - if (cros_gralloc_validate_handle(hnd)) { - cros_gralloc_error("Invalid handle."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (cros_gralloc_validate_reference(mod, hnd, &bo)) { - cros_gralloc_error("Invalid Reference."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && - (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { - cros_gralloc_error("Non-YUV format not compatible."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - - if (sw_access() & usage) { - void *vaddr = drv_bo_map(bo->bo, 0, 0, drv_bo_get_width(bo->bo), - drv_bo_get_height(bo->bo), 0, - &bo->map_data, 0); - - if (vaddr == MAP_FAILED) { - cros_gralloc_error("Mapping failed."); - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - - addr = static_cast<uint8_t*>(vaddr); - } - - for (size_t p = 0; p < drv_bo_get_num_planes(bo->bo); p++) - offsets[p] = drv_bo_get_plane_offset(bo->bo, p); - - switch (hnd->format) { - case DRM_FORMAT_NV12: - ycbcr->y = addr; - ycbcr->cb = addr + offsets[1]; - ycbcr->cr = addr + offsets[1] + 1; - ycbcr->ystride = drv_bo_get_plane_stride(bo->bo, 0); - ycbcr->cstride = drv_bo_get_plane_stride(bo->bo, 1); - ycbcr->chroma_step = 2; - break; - case DRM_FORMAT_YVU420: - ycbcr->y = addr; - ycbcr->cb = addr + offsets[2]; - ycbcr->cr = addr + offsets[1]; - ycbcr->ystride = drv_bo_get_plane_stride(bo->bo, 0); - ycbcr->cstride = drv_bo_get_plane_stride(bo->bo, 1); - ycbcr->chroma_step = 1; - break; - case DRM_FORMAT_UYVY: - ycbcr->y = addr + 1; - ycbcr->cb = addr; - ycbcr->cr = addr + 2; - ycbcr->ystride = drv_bo_get_plane_stride(bo->bo, 0); - ycbcr->cstride = drv_bo_get_plane_stride(bo->bo, 0); - ycbcr->chroma_step = 2; - break; - default: - return CROS_GRALLOC_ERROR_UNSUPPORTED; - } - - return CROS_GRALLOC_ERROR_NONE; -} - -static struct hw_module_methods_t cros_gralloc_module_methods = { - .open = cros_gralloc_open -}; - -struct cros_gralloc_module HAL_MODULE_INFO_SYM = { - .base = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = GRALLOC_MODULE_API_VERSION_0_2, - .hal_api_version = 0, - .id = GRALLOC_HARDWARE_MODULE_ID, - .name = "CrOS Gralloc", - .author = "Chrome OS", - .methods = &cros_gralloc_module_methods, - }, - .registerBuffer = cros_gralloc_register_buffer, - .unregisterBuffer = cros_gralloc_unregister_buffer, - .lock = cros_gralloc_lock, - .unlock = cros_gralloc_unlock, - .perform = cros_gralloc_perform, - .lock_ycbcr = cros_gralloc_lock_ycbcr, - }, - - .drv = NULL, -}; diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h new file mode 100644 index 00000000000..b1938c89c45 --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 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. + */ + +#ifndef CROS_GRALLOC_TYPES_H +#define CROS_GRALLOC_TYPES_H + +typedef enum { + CROS_GRALLOC_ERROR_NONE = 0, + CROS_GRALLOC_ERROR_BAD_DESCRIPTOR = 1, + CROS_GRALLOC_ERROR_BAD_HANDLE = 2, + CROS_GRALLOC_ERROR_BAD_VALUE = 3, + CROS_GRALLOC_ERROR_NOT_SHARED = 4, + CROS_GRALLOC_ERROR_NO_RESOURCES = 5, + CROS_GRALLOC_ERROR_UNDEFINED = 6, + CROS_GRALLOC_ERROR_UNSUPPORTED = 7, +} cros_gralloc_error_t; + +struct cros_gralloc_buffer_descriptor { + uint32_t width; + uint32_t height; + uint32_t consumer_usage; + uint32_t producer_usage; + uint32_t droid_format; + uint32_t drm_format; + uint64_t drv_usage; +}; + +#endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc b/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc new file mode 100644 index 00000000000..79d1113cc57 --- /dev/null +++ b/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc @@ -0,0 +1,351 @@ +/* + * Copyright 2016 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 "../cros_gralloc_driver.h" + +#include <hardware/gralloc.h> +#include <memory.h> + +struct gralloc0_module { + gralloc_module_t base; + std::unique_ptr<alloc_device_t> alloc; + std::unique_ptr<cros_gralloc_driver> driver; +}; + +/* This enumeration must match the one in <gralloc_drm.h>. + * The functions supported by this gralloc's temporary private API are listed + * below. Use of these functions is highly discouraged and should only be + * reserved for cases where no alternative to get same information (such as + * querying ANativeWindow) exists. + */ +// clang-format off +enum { + GRALLOC_DRM_GET_STRIDE, + GRALLOC_DRM_GET_FORMAT, + GRALLOC_DRM_GET_DIMENSIONS, + GRALLOC_DRM_GET_BACKING_STORE, +}; +// clang-format on + +static int64_t gralloc0_convert_flags(int flags) +{ + uint64_t usage = BO_USE_NONE; + + if (flags & GRALLOC_USAGE_CURSOR) + usage |= BO_USE_NONE; + if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) + usage |= BO_USE_SW_READ_RARELY; + if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) + usage |= BO_USE_SW_READ_OFTEN; + if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) + usage |= BO_USE_SW_WRITE_RARELY; + if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) + usage |= BO_USE_SW_WRITE_OFTEN; + if (flags & GRALLOC_USAGE_HW_TEXTURE) + usage |= BO_USE_TEXTURE; + if (flags & GRALLOC_USAGE_HW_RENDER) + usage |= BO_USE_RENDERING; + if (flags & GRALLOC_USAGE_HW_2D) + usage |= BO_USE_RENDERING; + if (flags & GRALLOC_USAGE_HW_COMPOSER) + /* HWC wants to use display hardware, but can defer to OpenGL. */ + usage |= BO_USE_SCANOUT | BO_USE_TEXTURE; + if (flags & GRALLOC_USAGE_HW_FB) + usage |= BO_USE_NONE; + if (flags & GRALLOC_USAGE_EXTERNAL_DISP) + /* + * This flag potentially covers external display for the normal drivers (i915, + * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it. + * */ + usage |= BO_USE_NONE; + if (flags & GRALLOC_USAGE_PROTECTED) + usage |= BO_USE_PROTECTED; + if (flags & GRALLOC_USAGE_HW_VIDEO_ENCODER) + /*HACK: See b/30054495 */ + usage |= BO_USE_SW_READ_OFTEN; + if (flags & GRALLOC_USAGE_HW_CAMERA_WRITE) + usage |= BO_USE_HW_CAMERA_WRITE; + if (flags & GRALLOC_USAGE_HW_CAMERA_READ) + usage |= BO_USE_HW_CAMERA_READ; + if (flags & GRALLOC_USAGE_HW_CAMERA_ZSL) + usage |= BO_USE_HW_CAMERA_ZSL; + if (flags & GRALLOC_USAGE_RENDERSCRIPT) + /* We use CPU for compute. */ + usage |= BO_USE_LINEAR; + + return usage; +} + +static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage, + buffer_handle_t *handle, int *stride) +{ + int32_t ret; + bool supported; + struct cros_gralloc_buffer_descriptor descriptor; + auto mod = (struct gralloc0_module *)dev->common.module; + + descriptor.width = w; + descriptor.height = h; + descriptor.droid_format = format; + descriptor.producer_usage = descriptor.consumer_usage = usage; + descriptor.drm_format = cros_gralloc_convert_format(format); + descriptor.drv_usage = gralloc0_convert_flags(usage); + + supported = mod->driver->is_supported(&descriptor); + if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) { + descriptor.drv_usage &= ~BO_USE_SCANOUT; + supported = mod->driver->is_supported(&descriptor); + } + + if (!supported) { + cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL flags: %u, " + "drv_format: %4.4s, drv_flags: %llu", + format, usage, reinterpret_cast<char *>(descriptor.drm_format), + static_cast<unsigned long long>(descriptor.drv_usage)); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + ret = mod->driver->allocate(&descriptor, handle); + if (ret) + return ret; + + auto hnd = cros_gralloc_convert_handle(*handle); + *stride = hnd->pixel_stride; + + return CROS_GRALLOC_ERROR_NONE; +} + +static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle) +{ + auto mod = (struct gralloc0_module *)dev->common.module; + return mod->driver->release(handle); +} + +static int gralloc0_close(struct hw_device_t *dev) +{ + /* Memory is freed by managed pointers on process close. */ + return CROS_GRALLOC_ERROR_NONE; +} + +static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) +{ + auto module = (struct gralloc0_module *)mod; + + if (module->alloc) { + *dev = &module->alloc->common; + return CROS_GRALLOC_ERROR_NONE; + } + + if (strcmp(name, GRALLOC_HARDWARE_GPU0)) { + cros_gralloc_error("Incorrect device name - %s.", name); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + module->driver = std::make_unique<cros_gralloc_driver>(); + if (module->driver->init()) { + cros_gralloc_error("Failed to initialize driver."); + return CROS_GRALLOC_ERROR_NO_RESOURCES; + } + + module->alloc = std::make_unique<alloc_device_t>(); + + module->alloc->alloc = gralloc0_alloc; + module->alloc->free = gralloc0_free; + module->alloc->common.tag = HARDWARE_DEVICE_TAG; + module->alloc->common.version = 0; + module->alloc->common.module = (hw_module_t *)mod; + module->alloc->common.close = gralloc0_close; + + *dev = &module->alloc->common; + return CROS_GRALLOC_ERROR_NONE; +} + +static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) +{ + auto mod = (struct gralloc0_module *)module; + + if (!mod->driver) { + mod->driver = std::make_unique<cros_gralloc_driver>(); + if (mod->driver->init()) { + cros_gralloc_error("Failed to initialize driver."); + return CROS_GRALLOC_ERROR_NO_RESOURCES; + } + } + + return mod->driver->retain(handle); +} + +static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) +{ + auto mod = (struct gralloc0_module *)module; + return mod->driver->release(handle); +} + +static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t handle, int usage, + int l, int t, int w, int h, void **vaddr) +{ + int32_t ret, fence; + uint64_t flags; + uint8_t *addr[DRV_MAX_PLANES]; + auto mod = (struct gralloc0_module *)module; + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) { + cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + fence = -1; + flags = gralloc0_convert_flags(usage); + ret = mod->driver->lock(handle, fence, flags, addr); + *vaddr = addr[0]; + return ret; +} + +static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle) +{ + auto mod = (struct gralloc0_module *)module; + return mod->driver->unlock(handle); +} + +static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) +{ + va_list args; + int32_t *out_format, ret; + uint64_t *out_store; + buffer_handle_t handle; + uint32_t *out_width, *out_height, *out_stride; + auto mod = (struct gralloc0_module *)module; + + switch (op) { + case GRALLOC_DRM_GET_STRIDE: + case GRALLOC_DRM_GET_FORMAT: + case GRALLOC_DRM_GET_DIMENSIONS: + case GRALLOC_DRM_GET_BACKING_STORE: + break; + default: + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + va_start(args, op); + + ret = CROS_GRALLOC_ERROR_NONE; + handle = va_arg(args, buffer_handle_t); + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + switch (op) { + case GRALLOC_DRM_GET_STRIDE: + out_stride = va_arg(args, uint32_t *); + *out_stride = hnd->pixel_stride; + break; + case GRALLOC_DRM_GET_FORMAT: + out_format = va_arg(args, int32_t *); + *out_format = hnd->droid_format; + break; + case GRALLOC_DRM_GET_DIMENSIONS: + out_width = va_arg(args, uint32_t *); + out_height = va_arg(args, uint32_t *); + *out_width = hnd->width; + *out_height = hnd->height; + break; + case GRALLOC_DRM_GET_BACKING_STORE: + out_store = va_arg(args, uint64_t *); + ret = mod->driver->get_backing_store(handle, out_store); + break; + default: + ret = CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + va_end(args); + + return ret; +} + +static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle, + int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr) +{ + uint64_t flags; + int32_t fence, ret; + uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; + auto mod = (struct gralloc0_module *)module; + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + cros_gralloc_error("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && + (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { + cros_gralloc_error("Non-YUV format not compatible."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + fence = -1; + flags = gralloc0_convert_flags(usage); + ret = mod->driver->lock(handle, fence, flags, addr); + + switch (hnd->format) { + case DRM_FORMAT_NV12: + ycbcr->y = addr[0]; + ycbcr->cb = addr[1]; + ycbcr->cr = addr[1] + 1; + ycbcr->ystride = hnd->strides[0]; + ycbcr->cstride = hnd->strides[1]; + ycbcr->chroma_step = 2; + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + ycbcr->y = addr[0]; + ycbcr->cb = addr[2]; + ycbcr->cr = addr[1]; + ycbcr->ystride = hnd->strides[0]; + ycbcr->cstride = hnd->strides[1]; + ycbcr->chroma_step = 1; + break; + default: + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + return ret; +} + +static struct hw_module_methods_t gralloc0_module_methods = {.open = gralloc0_open }; + +struct gralloc0_module HAL_MODULE_INFO_SYM = { + .base = + { + .common = + { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = GRALLOC_MODULE_API_VERSION_0_2, + .hal_api_version = 0, + .id = GRALLOC_HARDWARE_MODULE_ID, + .name = "CrOS Gralloc", + .author = "Chrome OS", + .methods = &gralloc0_module_methods, + }, + + .registerBuffer = gralloc0_register_buffer, + .unregisterBuffer = gralloc0_unregister_buffer, + .lock = gralloc0_lock, + .unlock = gralloc0_unlock, + .perform = gralloc0_perform, + .lock_ycbcr = gralloc0_lock_ycbcr, + }, + + .alloc = nullptr, + .driver = nullptr, +}; diff --git a/chromium/third_party/minigbm/src/drv.c b/chromium/third_party/minigbm/src/drv.c index fb79e127e4f..bcc8cfaf3fd 100644 --- a/chromium/third_party/minigbm/src/drv.c +++ b/chromium/third_party/minigbm/src/drv.c @@ -64,8 +64,7 @@ static struct backend *drv_get_backend(int fd) #ifdef DRV_AMDGPU &backend_amdgpu, #endif - &backend_cirrus, - &backend_evdi, + &backend_cirrus, &backend_evdi, #ifdef DRV_EXYNOS &backend_exynos, #endif @@ -90,11 +89,10 @@ static struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, - &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; - for(i = 0; i < ARRAY_SIZE(backend_list); i++) + for (i = 0; i < ARRAY_SIZE(backend_list); i++) if (!strcmp(drm_version->name, backend_list[i]->name)) { drmFreeVersion(drm_version); return backend_list[i]; @@ -109,7 +107,7 @@ struct driver *drv_create(int fd) struct driver *drv; int ret; - drv = (struct driver *) calloc(1, sizeof(*drv)); + drv = (struct driver *)calloc(1, sizeof(*drv)); if (!drv) return NULL; @@ -131,12 +129,20 @@ struct driver *drv_create(int fd) if (!drv->map_table) goto free_buffer_table; - LIST_INITHEAD(&drv->backend->combinations); + /* 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) + goto free_map_table; if (drv->backend->init) { ret = drv->backend->init(drv); - if (ret) + if (ret) { + free(drv->backend->combos.data); goto free_map_table; + } } return drv; @@ -162,11 +168,7 @@ void drv_destroy(struct driver *drv) drmHashDestroy(drv->buffer_table); drmHashDestroy(drv->map_table); - list_for_each_entry_safe(struct combination_list_element, elem, - &drv->backend->combinations, link) { - LIST_DEL(&elem->link); - free(elem); - } + free(drv->backend->combos.data); pthread_mutex_unlock(&drv->driver_lock); pthread_mutex_destroy(&drv->driver_lock); @@ -179,36 +181,35 @@ int drv_get_fd(struct driver *drv) return drv->fd; } -const char * -drv_get_name(struct driver *drv) +const char *drv_get_name(struct driver *drv) { return drv->backend->name; } -int drv_is_combination_supported(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier) +struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage) { + struct combination *curr, *best; if (format == DRM_FORMAT_NONE || usage == BO_USE_NONE) return 0; - list_for_each_entry(struct combination_list_element, elem, - &drv->backend->combinations, link) { - if (format == elem->combination.format && - usage == (elem->combination.usage & usage) && - modifier == elem->combination.modifier) - return 1; + 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)) + if (!best || best->metadata.priority < curr->metadata.priority) + best = curr; } - return 0; + return best; } -struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, - uint32_t format) +struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format) { struct bo *bo; - bo = (struct bo *) calloc(1, sizeof(*bo)); + bo = (struct bo *)calloc(1, sizeof(*bo)); if (!bo) return NULL; @@ -227,8 +228,8 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, return bo; } -struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, - uint32_t format, uint64_t flags) +struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, + uint64_t flags) { int ret; size_t plane; @@ -256,10 +257,8 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, return bo; } -struct bo *drv_bo_create_with_modifiers(struct driver *drv, - uint32_t width, uint32_t height, - uint32_t format, - const uint64_t *modifiers, uint32_t count) +struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count) { int ret; size_t plane; @@ -275,8 +274,7 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, if (!bo) return NULL; - ret = drv->backend->bo_create_with_modifiers(bo, width, height, - format, modifiers, count); + ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, count); if (ret) { free(bo); @@ -293,7 +291,6 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, return bo; } - void drv_bo_destroy(struct bo *bo) { size_t plane; @@ -344,8 +341,8 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) return bo; } -void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, - uint32_t height, uint32_t flags, void **map_data, size_t plane) +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) { void *ptr; uint8_t *addr; @@ -360,7 +357,7 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, pthread_mutex_lock(&bo->drv->driver_lock); if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - data = (struct map_info *) ptr; + data = (struct map_info *)ptr; data->refcount++; goto success; } @@ -377,23 +374,21 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, data->refcount = 1; data->addr = addr; data->handle = bo->handles[plane].u32; - drmHashInsert(bo->drv->buffer_table, bo->handles[plane].u32, - (void *) data); + drmHashInsert(bo->drv->map_table, bo->handles[plane].u32, (void *)data); success: - *map_data = (void *) data; + *map_data = data; offset = drv_bo_get_plane_stride(bo, plane) * y; offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *) data->addr; + addr = (uint8_t *)data->addr; addr += drv_bo_get_plane_offset(bo, plane) + offset; pthread_mutex_unlock(&bo->drv->driver_lock); - return (void *) addr; + return (void *)addr; } -int drv_bo_unmap(struct bo *bo, void *map_data) +int drv_bo_unmap(struct bo *bo, struct map_info *data) { - struct map_info *data = map_data; int ret = 0; assert(data); @@ -450,11 +445,9 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) int ret, fd; assert(plane < bo->num_planes); - ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, - DRM_CLOEXEC | DRM_RDWR, &fd); + ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); return (ret) ? ret : fd; - } uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane) @@ -477,7 +470,7 @@ uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane) uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane) { - assert(plane < bo->num_planes); + assert(plane < bo->num_planes); return bo->format_modifiers[plane]; } @@ -494,31 +487,6 @@ uint32_t drv_resolve_format(struct driver *drv, uint32_t format) return format; } -/* - * This function returns the stride for a given format, width and plane. - */ -int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) -{ - int stride = width * DIV_ROUND_UP(drv_bpp_from_format(format, plane), - 8); - - /* - * Only downsample for certain multiplanar formats which have horizontal - * subsampling for chroma planes. Only formats supported by our drivers - * are listed here -- add more as needed. - */ - if (plane != 0) { - switch (format) { - case DRM_FORMAT_NV12: - case DRM_FORMAT_YVU420: - stride = stride / 2; - break; - } - } - - return stride; -} - size_t drv_num_planes_from_format(uint32_t format) { switch (format) { @@ -571,8 +539,10 @@ size_t drv_num_planes_from_format(uint32_t format) case DRM_FORMAT_YVYU: return 1; case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: return 2; case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: return 3; } @@ -580,8 +550,7 @@ 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) +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; @@ -589,6 +558,7 @@ uint32_t drv_size_from_format(uint32_t format, uint32_t stride, switch (format) { case DRM_FORMAT_NV12: case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: vertical_subsampling = (plane == 0) ? 1 : 2; break; default: diff --git a/chromium/third_party/minigbm/src/drv.h b/chromium/third_party/minigbm/src/drv.h index 355ea45f03e..f478a665940 100644 --- a/chromium/third_party/minigbm/src/drv.h +++ b/chromium/third_party/minigbm/src/drv.h @@ -16,6 +16,7 @@ extern "C" { #define DRV_MAX_PLANES 4 +// clang-format off /* Use flags */ #define BO_USE_NONE 0 #define BO_USE_SCANOUT (1ull << 0) @@ -36,6 +37,7 @@ extern "C" { #define BO_USE_HW_CAMERA_READ (1ull << 14) #define BO_USE_HW_CAMERA_ZSL (1ull << 15) #define BO_USE_RENDERSCRIPT (1ull << 16) +#define BO_USE_TEXTURE (1ull << 17) /* This is our extension to <drm_fourcc.h>. We need to make sure we don't step * on the namespace of already defined formats, which can be done by using invalid @@ -43,11 +45,14 @@ extern "C" { */ #define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0') +#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8') #define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9') +// clang-format on struct driver; struct bo; +struct combination; union bo_handle { void *ptr; @@ -68,97 +73,72 @@ struct drv_import_fd_data { uint32_t format; }; -struct driver * -drv_create(int fd); +struct map_info { + void *addr; + size_t length; + uint32_t handle; + int32_t refcount; + void *priv; +}; + +struct driver *drv_create(int fd); -void -drv_destroy(struct driver *drv); +void drv_destroy(struct driver *drv); -int -drv_get_fd(struct driver *drv); +int drv_get_fd(struct driver *drv); -const char * -drv_get_name(struct driver *drv); +const char *drv_get_name(struct driver *drv); -int -drv_is_combination_supported(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier); +struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage); -struct bo * -drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, - uint32_t format); +struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format); -struct bo * -drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, - uint32_t format, uint64_t flags); +struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, + uint64_t flags); -struct bo * -drv_bo_create_with_modifiers(struct driver *drv, - uint32_t width, uint32_t height, - uint32_t format, - const uint64_t *modifiers, uint32_t count); +struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count); -void -drv_bo_destroy(struct bo *bo); +void drv_bo_destroy(struct bo *bo); -struct bo * -drv_bo_import(struct driver *drv, struct drv_import_fd_data *data); +struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data); -void * -drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, - uint32_t height, uint32_t flags, void **map_data, size_t plane); +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); -int -drv_bo_unmap(struct bo *bo, void *map_data); +int drv_bo_unmap(struct bo *bo, struct map_info *map_data); -uint32_t -drv_bo_get_width(struct bo *bo); +uint32_t drv_bo_get_width(struct bo *bo); -uint32_t -drv_bo_get_height(struct bo *bo); +uint32_t drv_bo_get_height(struct bo *bo); -uint32_t -drv_bo_get_stride_or_tiling(struct bo *bo); +uint32_t drv_bo_get_stride_or_tiling(struct bo *bo); -size_t -drv_bo_get_num_planes(struct bo *bo); +size_t drv_bo_get_num_planes(struct bo *bo); -union bo_handle -drv_bo_get_plane_handle(struct bo *bo, size_t plane); +union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane); -int -drv_bo_get_plane_fd(struct bo *bo, size_t plane); +int drv_bo_get_plane_fd(struct bo *bo, size_t plane); -uint32_t -drv_bo_get_plane_offset(struct bo *bo, size_t plane); +uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane); -uint32_t -drv_bo_get_plane_size(struct bo *bo, size_t plane); +uint32_t drv_bo_get_plane_size(struct bo *bo, size_t plane); -uint32_t -drv_bo_get_plane_stride(struct bo *bo, size_t plane); +uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane); -uint64_t -drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane); +uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane); -uint32_t -drv_bo_get_format(struct bo *bo); +uint32_t drv_bo_get_format(struct bo *bo); -uint32_t -drv_resolve_format(struct driver *drv, uint32_t format); +uint32_t drv_bo_get_stride_in_pixels(struct bo *bo); -int -drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); +uint32_t drv_resolve_format(struct driver *drv, uint32_t format); -size_t -drv_num_planes_from_format(uint32_t format); +size_t drv_num_planes_from_format(uint32_t format); -uint32_t -drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, - size_t plane); +uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane); -uint32_t -drv_num_buffers_per_bo(struct bo *bo); +uint32_t drv_num_buffers_per_bo(struct bo *bo); #ifdef __cplusplus } diff --git a/chromium/third_party/minigbm/src/drv_priv.h b/chromium/third_party/minigbm/src/drv_priv.h index 62492c284cb..df5c8e97b26 100644 --- a/chromium/third_party/minigbm/src/drv_priv.h +++ b/chromium/third_party/minigbm/src/drv_priv.h @@ -13,10 +13,8 @@ #include <sys/types.h> #include "drv.h" -#include "list.h" -struct bo -{ +struct bo { struct driver *drv; uint32_t width; uint32_t height; @@ -41,43 +39,55 @@ struct driver { pthread_mutex_t driver_lock; }; -struct map_info { - void *addr; - size_t length; - uint32_t handle; - int32_t refcount; - void *priv; +struct kms_item { + uint32_t format; + uint64_t modifier; + uint64_t usage; }; -struct supported_combination { - uint32_t format; +struct format_metadata { + uint32_t priority; + uint32_t tiling; uint64_t modifier; +}; + +struct combination { + uint32_t format; + struct format_metadata metadata; uint64_t usage; }; -struct combination_list_element { - struct supported_combination combination; - struct list_head link; +struct combinations { + struct combination *data; + uint32_t size; + uint32_t allocations; }; -struct backend -{ +struct backend { char *name; int (*init)(struct driver *drv); void (*close)(struct driver *drv); - int (*bo_create)(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); - int (*bo_create_with_modifiers)(struct bo *bo, - uint32_t width, uint32_t height, - uint32_t format, - const uint64_t *modifiers, - uint32_t count); + int (*bo_create)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags); + int (*bo_create_with_modifiers)(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count); int (*bo_destroy)(struct bo *bo); int (*bo_import)(struct bo *bo, struct drv_import_fd_data *data); - void* (*bo_map)(struct bo *bo, struct map_info *data, size_t plane); + void *(*bo_map)(struct bo *bo, struct map_info *data, size_t plane); int (*bo_unmap)(struct bo *bo, struct map_info *data); uint32_t (*resolve_format)(uint32_t format); - struct list_head combinations; + struct combinations combos; }; +// clang-format off +#define BO_USE_RENDER_MASK BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | \ + BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | \ + BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE + +#define BO_USE_TEXTURE_MASK BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE + +#define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_NONE } +// clang-format on + #endif diff --git a/chromium/third_party/minigbm/src/evdi.c b/chromium/third_party/minigbm/src/evdi.c index 988797b2f8c..f66fb2d48bb 100644 --- a/chromium/third_party/minigbm/src/evdi.c +++ b/chromium/third_party/minigbm/src/evdi.c @@ -8,23 +8,20 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[2] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int evdi_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_evdi = -{ +struct backend backend_evdi = { .name = "evdi", .init = evdi_init, .bo_create = drv_dumb_bo_create, @@ -32,4 +29,3 @@ struct backend backend_evdi = .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, }; - diff --git a/chromium/third_party/minigbm/src/exynos.c b/chromium/third_party/minigbm/src/exynos.c index 4dcf6043cc1..0d935ebf13c 100644 --- a/chromium/third_party/minigbm/src/exynos.c +++ b/chromium/third_party/minigbm/src/exynos.c @@ -6,37 +6,41 @@ #ifdef DRV_EXYNOS +// clang-format off #include <assert.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <xf86drm.h> #include <exynos_drm.h> +// clang-format on #include "drv_priv.h" #include "helpers.h" #include "util.h" -static struct supported_combination combos[3] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +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_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { size_t plane; @@ -73,8 +77,8 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, ret = drmIoctl(bo->drv->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_EXYNOS_GEM_CREATE failed " - "(size=%zu)\n", size); + fprintf(stderr, "drv: DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", + size); goto cleanup_planes; } @@ -84,16 +88,13 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, return 0; cleanup_planes: - for ( ; plane != 0; plane--) { + for (; plane != 0; plane--) { struct drm_gem_close gem_close; memset(&gem_close, 0, sizeof(gem_close)); gem_close.handle = bo->handles[plane - 1].u32; - int gem_close_ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, - &gem_close); + int gem_close_ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); if (gem_close_ret) { - fprintf(stderr, - "drv: DRM_IOCTL_GEM_CLOSE failed: %d\n", - gem_close_ret); + fprintf(stderr, "drv: DRM_IOCTL_GEM_CLOSE failed: %d\n", gem_close_ret); } } @@ -104,8 +105,7 @@ cleanup_planes: * Use dumb mapping with exynos even though a GEM buffer is created. * libdrm does the same thing in exynos_drm.c */ -struct backend backend_exynos = -{ +struct backend backend_exynos = { .name = "exynos", .init = exynos_init, .bo_create = exynos_bo_create, diff --git a/chromium/third_party/minigbm/src/gbm.c b/chromium/third_party/minigbm/src/gbm.c index 6ad32ce6bbe..ab576cf926d 100644 --- a/chromium/third_party/minigbm/src/gbm.c +++ b/chromium/third_party/minigbm/src/gbm.c @@ -13,44 +13,38 @@ #include <xf86drm.h> #include "drv.h" -#include "gbm_priv.h" #include "gbm_helpers.h" +#include "gbm_priv.h" #include "util.h" -PUBLIC int -gbm_device_get_fd(struct gbm_device *gbm) +PUBLIC int gbm_device_get_fd(struct gbm_device *gbm) { 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 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) { uint64_t drv_usage; - if (usage & GBM_BO_USE_CURSOR && - usage & GBM_BO_USE_RENDERING) + if (usage & GBM_BO_USE_CURSOR && usage & GBM_BO_USE_RENDERING) return 0; drv_usage = gbm_convert_flags(usage); - return drv_is_combination_supported(gbm->drv, format, drv_usage, - DRM_FORMAT_MOD_NONE); + return (drv_get_combination(gbm->drv, format, drv_usage) != NULL); } PUBLIC struct gbm_device *gbm_create_device(int fd) { struct gbm_device *gbm; - gbm = (struct gbm_device*) malloc(sizeof(*gbm)); + gbm = (struct gbm_device *)malloc(sizeof(*gbm)); if (!gbm) return NULL; @@ -70,12 +64,10 @@ PUBLIC void gbm_device_destroy(struct gbm_device *gbm) 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 flags) { - struct gbm_surface *surface = - (struct gbm_surface*) malloc(sizeof(*surface)); + struct gbm_surface *surface = (struct gbm_surface *)malloc(sizeof(*surface)); if (!surface) return NULL; @@ -93,8 +85,7 @@ 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) { } @@ -102,7 +93,7 @@ static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) { struct gbm_bo *bo; - bo = (struct gbm_bo*) calloc(1, sizeof(*bo)); + bo = (struct gbm_bo *)calloc(1, sizeof(*bo)); if (!bo) return NULL; @@ -112,9 +103,8 @@ static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t 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 flags) +PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, + uint32_t format, uint32_t flags) { struct gbm_bo *bo; @@ -126,8 +116,7 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, if (!bo) return NULL; - bo->bo = drv_bo_create(gbm->drv, width, height, format, - gbm_convert_flags(flags)); + bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_flags(flags)); if (!bo->bo) { free(bo); @@ -137,12 +126,9 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, 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) +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; @@ -151,9 +137,7 @@ PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers(struct gbm_device *gbm, if (!bo) return NULL; - bo->bo = drv_bo_create_with_modifiers(gbm->drv, - width, height, format, - modifiers, count); + bo->bo = drv_bo_create_with_modifiers(gbm->drv, width, height, format, modifiers, count); if (!bo->bo) { free(bo); @@ -175,9 +159,8 @@ PUBLIC void gbm_bo_destroy(struct gbm_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_bo *bo; struct drv_import_fd_data drv_data; @@ -211,14 +194,10 @@ gbm_bo_import(struct gbm_device *gbm, uint32_t type, 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]; + drv_data.format_modifiers[i] = fd_planar_data->format_modifiers[i]; drv_data.sizes[i] = drv_size_from_format( - drv_data.format, - drv_data.strides[i], - drv_data.height, - i); + drv_data.format, drv_data.strides[i], drv_data.height, i); } for (i = num_planes; i < GBM_MAX_PLANES; i++) @@ -247,131 +226,110 @@ gbm_bo_import(struct gbm_device *gbm, uint32_t type, 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 flags, uint32_t *stride, void **map_data, - size_t plane) +PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t flags, uint32_t *stride, void **map_data, size_t plane) { if (!bo || width == 0 || height == 0 || !stride || !map_data) return NULL; *stride = gbm_bo_get_plane_stride(bo, plane); - return drv_bo_map(bo->bo, x, y, width, height, 0, map_data, plane); + return drv_bo_map(bo->bo, x, y, width, height, 0, (struct map_info **)map_data, plane); } -PUBLIC void -gbm_bo_unmap(struct gbm_bo *bo, void *map_data) +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) +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 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 gbm_bo_get_plane_stride(bo, 0); } -PUBLIC uint32_t -gbm_bo_get_stride_or_tiling(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) +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) +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) +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) +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) +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) +PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) { - return (union gbm_bo_handle) drv_bo_get_plane_handle(bo->bo, plane).u64; + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; } -PUBLIC int -gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) +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) +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) +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) +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) +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; } diff --git a/chromium/third_party/minigbm/src/gbm.h b/chromium/third_party/minigbm/src/gbm.h index 1fb338f98e3..312b09892dc 100644 --- a/chromium/third_party/minigbm/src/gbm.h +++ b/chromium/third_party/minigbm/src/gbm.h @@ -239,6 +239,10 @@ enum gbm_bo_flags { * buffer. */ GBM_BO_USE_LINEAR = (1 << 4), + /** + * The buffer will be used as a texture that will be sampled from. + */ + GBM_BO_USE_TEXTURING = (1 << 5), }; int diff --git a/chromium/third_party/minigbm/src/gbm_helpers.c b/chromium/third_party/minigbm/src/gbm_helpers.c index c60a315b2cc..2b9ce23e6a5 100644 --- a/chromium/third_party/minigbm/src/gbm_helpers.c +++ b/chromium/third_party/minigbm/src/gbm_helpers.c @@ -22,6 +22,8 @@ uint64_t gbm_convert_flags(uint32_t flags) usage |= BO_USE_CURSOR_64X64; if (flags & GBM_BO_USE_RENDERING) usage |= BO_USE_RENDERING; + if (flags & GBM_BO_USE_TEXTURING) + usage |= BO_USE_TEXTURE; if (flags & GBM_BO_USE_LINEAR) usage |= BO_USE_LINEAR; diff --git a/chromium/third_party/minigbm/src/gbm_priv.h b/chromium/third_party/minigbm/src/gbm_priv.h index eb29f1be8a7..3dc1e594458 100644 --- a/chromium/third_party/minigbm/src/gbm_priv.h +++ b/chromium/third_party/minigbm/src/gbm_priv.h @@ -8,23 +8,20 @@ #define GBM_PRIV_H #include <stdint.h> -#include <sys/types.h> #include <stdlib.h> +#include <sys/types.h> #include "drv.h" #include "gbm.h" -struct gbm_device -{ +struct gbm_device { struct driver *drv; }; -struct gbm_surface -{ +struct gbm_surface { }; -struct gbm_bo -{ +struct gbm_bo { struct gbm_device *gbm; struct bo *bo; uint32_t gbm_format; diff --git a/chromium/third_party/minigbm/src/gma500.c b/chromium/third_party/minigbm/src/gma500.c index d8932fb40da..5b08bc32b09 100644 --- a/chromium/third_party/minigbm/src/gma500.c +++ b/chromium/third_party/minigbm/src/gma500.c @@ -8,20 +8,20 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[1] = { - {DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_RGBX8888 }; static int gma500_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_gma500 = -{ +struct backend backend_gma500 = { .name = "gma500", .init = gma500_init, .bo_create = drv_dumb_bo_create, diff --git a/chromium/third_party/minigbm/src/helpers.c b/chromium/third_party/minigbm/src/helpers.c index 87aad9df17b..806c152ee6f 100644 --- a/chromium/third_party/minigbm/src/helpers.c +++ b/chromium/third_party/minigbm/src/helpers.c @@ -5,6 +5,7 @@ */ #include <assert.h> +#include <errno.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -17,7 +18,22 @@ #include "helpers.h" #include "util.h" -int drv_bpp_from_format(uint32_t format, size_t plane) +static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane) +{ + + if (plane != 0) { + switch (format) { + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + stride = DIV_ROUND_UP(stride, 2); + break; + } + } + + return stride; +} + +static uint32_t bpp_from_format(uint32_t format, size_t plane) { assert(plane < drv_num_planes_from_format(format)); @@ -27,27 +43,12 @@ int drv_bpp_from_format(uint32_t format, size_t plane) case DRM_FORMAT_R8: case DRM_FORMAT_RGB332: case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: return 8; - /* - * NV12 is laid out as follows. Each letter represents a byte. - * Y plane: - * Y0_0, Y0_1, Y0_2, Y0_3, ..., Y0_N - * Y1_0, Y1_1, Y1_2, Y1_3, ..., Y1_N - * ... - * YM_0, YM_1, YM_2, YM_3, ..., YM_N - * CbCr plane: - * Cb01_01, Cr01_01, Cb01_23, Cr01_23, ..., Cb01_(N-1)N, Cr01_(N-1)N - * Cb23_01, Cr23_01, Cb23_23, Cr23_23, ..., Cb23_(N-1)N, Cr23_(N-1)N - * ... - * Cb(M-1)M_01, Cr(M-1)M_01, ..., Cb(M-1)M_(N-1)N, Cr(M-1)M_(N-1)N - * - * Pixel (0, 0) requires Y0_0, Cb01_01 and Cr01_01. Pixel (0, 1) requires - * Y0_1, Cb01_01 and Cr01_01. So for a single pixel, 2 bytes of luma data - * are required. - */ case DRM_FORMAT_NV12: - return (plane == 0) ? 8 : 16; + case DRM_FORMAT_NV21: + return (plane == 0) ? 8 : 4; case DRM_FORMAT_ABGR1555: case DRM_FORMAT_ABGR4444: @@ -103,13 +104,35 @@ int drv_bpp_from_format(uint32_t format, size_t plane) return 0; } +uint32_t drv_bo_get_stride_in_pixels(struct bo *bo) +{ + uint32_t bytes_per_pixel = DIV_ROUND_UP(bpp_from_format(bo->format, 0), 8); + return DIV_ROUND_UP(bo->strides[0], bytes_per_pixel); +} + /* - * This function fills in the buffer object given driver aligned dimensions - * and a format. This function assumes there is just one kernel buffer per - * buffer object. + * This function returns the stride for a given format, width and plane. */ -int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format) +uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) +{ + uint32_t stride = DIV_ROUND_UP(width * bpp_from_format(format, plane), 8); + + /* + * The stride of Android YV12 buffers is required to be aligned to 16 bytes + * (see <system/graphics.h>). + */ + if (format == DRM_FORMAT_YVU420_ANDROID) + stride = (plane == 0) ? ALIGN(stride, 32) : ALIGN(stride, 16); + + return stride; +} + +/* + * This function fills in the buffer object given the driver aligned stride of + * the first plane, height and a format. This function assumes there is just + * one kernel buffer per buffer object. + */ +int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, uint32_t format) { size_t p, num_planes; @@ -118,33 +141,54 @@ int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, num_planes = drv_num_planes_from_format(format); assert(num_planes); + /* + * HAL_PIXEL_FORMAT_YV12 requires that (see <system/graphics.h>): + * - the aligned height is same as the buffer's height. + * - the chroma stride is 16 bytes aligned, i.e., the luma's strides + * is 32 bytes aligned. + */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) { + assert(aligned_height == bo->height); + assert(stride == ALIGN(stride, 32)); + } + for (p = 0; p < num_planes; p++) { - bo->strides[p] = drv_stride_from_format(format, width, p); - bo->sizes[p] = drv_size_from_format(format, bo->strides[p], - height, p); + bo->strides[p] = subsample_stride(stride, format, p); + bo->sizes[p] = drv_size_from_format(format, bo->strides[p], aligned_height, p); bo->offsets[p] = offset; offset += bo->sizes[p]; } - bo->total_size = bo->offsets[bo->num_planes - 1] + - bo->sizes[bo->num_planes - 1]; - + bo->total_size = offset; return 0; } -int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { - struct drm_mode_create_dumb create_dumb; int ret; + size_t plane; + uint32_t aligned_width, aligned_height; + struct drm_mode_create_dumb create_dumb; + + aligned_width = width; + aligned_height = height; + if (format == DRM_FORMAT_YVU420_ANDROID) { + /* + * Align width to 32 pixels, so chroma strides are 16 bytes as + * Android requires. + */ + aligned_width = ALIGN(width, 32); + } - /* Only single-plane formats are supported */ - assert(drv_num_planes_from_format(format) == 1); + if (format == DRM_FORMAT_YVU420_ANDROID || format == DRM_FORMAT_YVU420) { + aligned_height = 3 * DIV_ROUND_UP(height, 2); + } memset(&create_dumb, 0, sizeof(create_dumb)); - create_dumb.height = height; - create_dumb.width = width; - create_dumb.bpp = drv_bpp_from_format(format, 0); + create_dumb.height = aligned_height; + create_dumb.width = aligned_width; + create_dumb.bpp = bpp_from_format(format, 0); create_dumb.flags = 0; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); @@ -153,13 +197,12 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, return ret; } - bo->width = width; - bo->height = height; - bo->handles[0].u32 = create_dumb.handle; - bo->offsets[0] = 0; - bo->total_size = bo->sizes[0] = create_dumb.size; - bo->strides[0] = create_dumb.pitch; + drv_bo_from_format(bo, create_dumb.pitch, height, format); + + for (plane = 0; plane < bo->num_planes; plane++) + bo->handles[plane].u32 = create_dumb.handle; + bo->total_size = create_dumb.size; return 0; } @@ -173,8 +216,8 @@ int drv_dumb_bo_destroy(struct bo *bo) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MODE_DESTROY_DUMB failed " - "(handle=%x)\n", bo->handles[0].u32); + fprintf(stderr, "drv: DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", + bo->handles[0].u32); return ret; } @@ -200,9 +243,8 @@ int drv_gem_bo_destroy(struct bo *bo) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_GEM_CLOSE failed " - "(handle=%x) error %d\n", - bo->handles[plane].u32, ret); + fprintf(stderr, "drv: DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", + bo->handles[plane].u32, ret); error = ret; } } @@ -220,12 +262,11 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) memset(&prime_handle, 0, sizeof(prime_handle)); prime_handle.fd = data->fds[plane]; - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, - &prime_handle); + ret = drmIoctl(bo->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); + fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed (fd=%u)\n", + prime_handle.fd); /* * Need to call GEM close on planes that were opened, @@ -269,43 +310,38 @@ void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane) if (bo->handles[i].u32 == bo->handles[plane].u32) data->length += bo->sizes[i]; - return mmap(0, data->length, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, map_dumb.offset); + return mmap(0, data->length, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + map_dumb.offset); } -uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, - size_t plane) +uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane) { void *count; uintptr_t num = 0; if (!drmHashLookup(drv->buffer_table, bo->handles[plane].u32, &count)) - num = (uintptr_t) (count); + num = (uintptr_t)(count); return num; } -void drv_increment_reference_count(struct driver *drv, struct bo *bo, - size_t plane) +void drv_increment_reference_count(struct driver *drv, struct bo *bo, size_t plane) { uintptr_t num = drv_get_reference_count(drv, bo, plane); /* If a value isn't in the table, drmHashDelete is a no-op */ drmHashDelete(drv->buffer_table, bo->handles[plane].u32); - drmHashInsert(drv->buffer_table, bo->handles[plane].u32, - (void *) (num + 1)); + drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num + 1)); } -void drv_decrement_reference_count(struct driver *drv, struct bo *bo, - size_t plane) +void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t plane) { uintptr_t num = drv_get_reference_count(drv, bo, plane); drmHashDelete(drv->buffer_table, bo->handles[plane].u32); if (num > 0) - drmHashInsert(drv->buffer_table, bo->handles[plane].u32, - (void *) (num - 1)); + drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num - 1)); } uint32_t drv_log_base2(uint32_t value) @@ -318,81 +354,74 @@ uint32_t drv_log_base2(uint32_t value) return ret; } -/* Inserts a combination into list -- caller should have lock on driver. */ -void drv_insert_supported_combination(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier) +int drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, + uint64_t usage) { - struct combination_list_element *elem; + struct combinations *combos = &drv->backend->combos; + if (combos->size >= combos->allocations) { + struct combination *new_data; + combos->allocations *= 2; + new_data = realloc(combos->data, combos->allocations * sizeof(*combos->data)); + if (!new_data) + return -ENOMEM; + + combos->data = new_data; + } - elem = calloc(1, sizeof(*elem)); - elem->combination.format = format; - elem->combination.modifier = modifier; - elem->combination.usage = usage; - LIST_ADD(&elem->link, &drv->backend->combinations); + combos->data[combos->size].format = format; + combos->data[combos->size].metadata.priority = metadata->priority; + combos->data[combos->size].metadata.tiling = metadata->tiling; + combos->data[combos->size].metadata.modifier = metadata->modifier; + combos->data[combos->size].usage = usage; + combos->size++; + return 0; } -void drv_insert_combinations(struct driver *drv, struct supported_combination *combos, - uint32_t size) +int drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, + struct format_metadata *metadata, uint64_t usage) { - unsigned int i; - - pthread_mutex_lock(&drv->driver_lock); - - for (i = 0; i < size; i++) - drv_insert_supported_combination(drv, combos[i].format, - combos[i].usage, - combos[i].modifier); + int ret; + uint32_t i; + for (i = 0; i < num_formats; i++) { + ret = drv_add_combination(drv, formats[i], metadata, usage); + if (ret) + return ret; + } - pthread_mutex_unlock(&drv->driver_lock); + return 0; } -void drv_modify_supported_combination(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier) +void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, + uint64_t usage) { - /* - * Attempts to add the specified usage to an existing {format, modifier} - * pair. If the pair is not present, a new combination is created. - */ - int found = 0; - - pthread_mutex_lock(&drv->driver_lock); - - list_for_each_entry(struct combination_list_element, - elem, &drv->backend->combinations, link) { - if (elem->combination.format == format && - elem->combination.modifier == modifier) { - elem->combination.usage |= usage; - found = 1; - } + uint32_t i; + struct combination *combo; + /* Attempts to add the specified usage to an existing combination. */ + for (i = 0; i < drv->backend->combos.size; i++) { + combo = &drv->backend->combos.data[i]; + if (combo->format == format && combo->metadata.tiling == metadata->tiling && + combo->metadata.modifier == metadata->modifier) + combo->usage |= usage; } - - - if (!found) - drv_insert_supported_combination(drv, format, usage, modifier); - - pthread_mutex_unlock(&drv->driver_lock); } -int drv_add_kms_flags(struct driver *drv) +struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items) { - int ret; - uint32_t i, j; uint64_t flag, usage; + struct kms_item *items; + uint32_t i, j, k, allocations, item_size; + drmModePlanePtr plane; drmModePropertyPtr prop; drmModePlaneResPtr resources; drmModeObjectPropertiesPtr props; - /* - * All current drivers can scanout XRGB8888/ARGB8888 as a primary plane. - * Some older kernel versions can only return overlay planes, so add the - * combination here. Note that the kernel disregards the alpha component - * of ARGB unless it's an overlay plane. - */ - drv_modify_supported_combination(drv, DRM_FORMAT_XRGB8888, - BO_USE_SCANOUT, 0); - drv_modify_supported_combination(drv, DRM_FORMAT_ARGB8888, - BO_USE_SCANOUT, 0); + /* Start with a power of 2 number of allocations. */ + allocations = 2; + item_size = 0; + items = calloc(allocations, sizeof(*items)); + if (!items) + goto out; /* * The ability to return universal planes is only complete on @@ -406,27 +435,24 @@ int drv_add_kms_flags(struct driver *drv) resources = drmModeGetPlaneResources(drv->fd); if (!resources) - goto err; + goto out; for (i = 0; i < resources->count_planes; i++) { - plane = drmModeGetPlane(drv->fd, resources->planes[i]); - if (!plane) - goto err; + goto out; - props = drmModeObjectGetProperties(drv->fd, plane->plane_id, - DRM_MODE_OBJECT_PLANE); + props = drmModeObjectGetProperties(drv->fd, plane->plane_id, DRM_MODE_OBJECT_PLANE); if (!props) - goto err; + goto out; for (j = 0; j < props->count_props; j++) { - prop = drmModeGetProperty(drv->fd, props->props[j]); if (prop) { if (strcmp(prop->name, "type") == 0) { flag = props->prop_values[j]; } + drmModeFreeProperty(prop); } } @@ -443,19 +469,82 @@ int drv_add_kms_flags(struct driver *drv) assert(0); } - for (j = 0; j < plane->count_formats; j++) - drv_modify_supported_combination(drv, plane->formats[j], - usage, 0); + for (j = 0; j < plane->count_formats; j++) { + bool found = false; + for (k = 0; k < item_size; k++) { + if (items[k].format == plane->formats[j] && + items[k].modifier == DRM_FORMAT_MOD_NONE) { + items[k].usage |= usage; + found = true; + break; + } + } + + if (!found && item_size >= allocations) { + struct kms_item *new_data = NULL; + allocations *= 2; + new_data = realloc(items, allocations * sizeof(*items)); + if (!new_data) { + item_size = 0; + goto out; + } + + items = new_data; + } + + if (!found) { + items[item_size].format = plane->formats[j]; + items[item_size].modifier = DRM_FORMAT_MOD_NONE; + items[item_size].usage = usage; + item_size++; + } + } drmModeFreeObjectProperties(props); drmModeFreePlane(plane); - } drmModeFreePlaneResources(resources); - return 0; +out: + if (items && item_size == 0) { + free(items); + items = NULL; + } -err: - ret = -1; - return ret; + *num_items = item_size; + return items; +} + +int drv_modify_linear_combinations(struct driver *drv) +{ + uint32_t i, j, num_items; + struct kms_item *items; + struct combination *combo; + + /* + * All current drivers can scanout linear XRGB8888/ARGB8888 as a primary + * plane and as a cursor. Some drivers don't support + * drmModeGetPlaneResources, so add the combination here. Note that the + * kernel disregards the alpha component of ARGB unless it's an overlay + * plane. + */ + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, + BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, + BO_USE_CURSOR | BO_USE_SCANOUT); + + items = drv_query_kms(drv, &num_items); + if (!items || !num_items) + return 0; + + for (i = 0; i < num_items; i++) { + for (j = 0; j < drv->backend->combos.size; j++) { + combo = &drv->backend->combos.data[j]; + if (items[i].format == combo->format) + combo->usage |= BO_USE_SCANOUT; + } + } + + free(items); + return 0; } diff --git a/chromium/third_party/minigbm/src/helpers.h b/chromium/third_party/minigbm/src/helpers.h index 64e8489e391..b42a3c25111 100644 --- a/chromium/third_party/minigbm/src/helpers.h +++ b/chromium/third_party/minigbm/src/helpers.h @@ -9,28 +9,24 @@ #include "drv.h" -int drv_bpp_from_format(uint32_t format, size_t plane); -int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format); -int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); +uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); +int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, uint32_t format); +int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags); int drv_dumb_bo_destroy(struct bo *bo); int drv_gem_bo_destroy(struct bo *bo); int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data); void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane); -uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, - size_t plane); -void drv_increment_reference_count(struct driver *drv, struct bo *bo, - size_t plane); -void drv_decrement_reference_count(struct driver *drv, struct bo *bo, - size_t plane); +uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane); +void drv_increment_reference_count(struct driver *drv, struct bo *bo, size_t plane); +void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t plane); uint32_t drv_log_base2(uint32_t value); -void drv_insert_supported_combination(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier); -void drv_insert_combinations(struct driver *drv, - struct supported_combination *combos, - uint32_t size); -void drv_modify_supported_combination(struct driver *drv, uint32_t format, - uint64_t usage, uint64_t modifier); -int drv_add_kms_flags(struct driver *drv); +int drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, + uint64_t usage); +int drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, + struct format_metadata *metadata, uint64_t usage); +void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, + uint64_t usage); +struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items); +int drv_modify_linear_combinations(struct driver *drv); #endif diff --git a/chromium/third_party/minigbm/src/i915.c b/chromium/third_party/minigbm/src/i915.c index 2c6645bf2cb..59995b26767 100644 --- a/chromium/third_party/minigbm/src/i915.c +++ b/chromium/third_party/minigbm/src/i915.c @@ -8,7 +8,7 @@ #include <errno.h> #include <i915_drm.h> -#include <intel_bufmgr.h> +#include <stdio.h> #include <string.h> #include <sys/mman.h> #include <xf86drm.h> @@ -17,331 +17,413 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[19] = { - {DRM_FORMAT_ARGB1555, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_GR88, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_R8, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB1555, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, -}; +#define I915_CACHELINE_SIZE 64 +#define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -struct i915_device -{ - int gen; - drm_intel_bufmgr *mgr; - uint32_t count; -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, + DRM_FORMAT_XRGB8888 }; -struct i915_bo -{ - drm_intel_bo *ibos[DRV_MAX_PLANES]; +static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_NV12, + DRM_FORMAT_R8, DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; + +struct i915_device { + uint32_t gen; + int32_t has_llc; }; -static int get_gen(int device_id) +static uint32_t i915_get_gen(int device_id) { - const uint16_t gen3_ids[] = {0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, - 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011}; + const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, + 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 }; unsigned i; - for(i = 0; i < ARRAY_SIZE(gen3_ids); i++) + for (i = 0; i < ARRAY_SIZE(gen3_ids); i++) if (gen3_ids[i] == device_id) return 3; return 4; } -static void i915_align_dimensions(struct driver *drv, uint32_t tiling_mode, - uint32_t *width, uint32_t *height, int bpp) +static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) +{ + uint32_t i; + struct combination *combo; + + /* + * Older hardware can't scanout Y-tiled formats. Newer devices can, and + * report this functionality via format modifiers. + */ + for (i = 0; i < drv->backend->combos.size; i++) { + combo = &drv->backend->combos.data[i]; + if (combo->format == item->format) { + if ((combo->metadata.tiling == I915_TILING_Y && + item->modifier == I915_FORMAT_MOD_Y_TILED) || + (combo->metadata.tiling == I915_TILING_X && + item->modifier == I915_FORMAT_MOD_X_TILED)) { + combo->metadata.modifier = item->modifier; + combo->usage |= item->usage; + } else if (combo->metadata.tiling != I915_TILING_Y) { + combo->usage |= item->usage; + } + } + } + + return 0; +} + +static int i915_add_combinations(struct driver *drv) { - struct i915_device *i915_dev = (struct i915_device *)drv->priv; - uint32_t width_alignment = 4, height_alignment = 4; + int ret; + uint32_t i, num_items; + struct kms_item *items; + struct format_metadata metadata; + uint64_t render_flags, texture_flags; + + render_flags = BO_USE_RENDER_MASK; + texture_flags = BO_USE_TEXTURE_MASK; + + metadata.tiling = I915_TILING_NONE; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_flags); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, texture_flags); + if (ret) + return ret; + + ret = drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_flags); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + + render_flags &= ~BO_USE_SW_WRITE_OFTEN; + render_flags &= ~BO_USE_SW_READ_OFTEN; + render_flags &= ~BO_USE_LINEAR; + + texture_flags &= ~BO_USE_SW_WRITE_OFTEN; + texture_flags &= ~BO_USE_SW_READ_OFTEN; + texture_flags &= ~BO_USE_LINEAR; + + metadata.tiling = I915_TILING_X; + metadata.priority = 2; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_flags); + if (ret) + return ret; + + ret = drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_flags); + if (ret) + return ret; + + metadata.tiling = I915_TILING_Y; + metadata.priority = 3; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_flags); + if (ret) + return ret; + + ret = drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_flags); + if (ret) + return ret; + + items = drv_query_kms(drv, &num_items); + if (!items || !num_items) + return 0; + + for (i = 0; i < num_items; i++) { + ret = i915_add_kms_item(drv, &items[i]); + if (ret) { + free(items); + return ret; + } + } + + free(items); + return 0; +} - switch (tiling_mode) { +static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride, + uint32_t *aligned_height) +{ + struct i915_device *i915 = bo->drv->priv; + uint32_t horizontal_alignment = 4; + uint32_t vertical_alignment = 4; + + switch (tiling) { default: case I915_TILING_NONE: - width_alignment = 64 / bpp; + horizontal_alignment = 64; break; case I915_TILING_X: - width_alignment = 512 / bpp; - height_alignment = 8; + horizontal_alignment = 512; + vertical_alignment = 8; break; case I915_TILING_Y: - if (i915_dev->gen == 3) { - width_alignment = 512 / bpp; - height_alignment = 8; - } else { - width_alignment = 128 / bpp; - height_alignment = 32; + if (i915->gen == 3) { + horizontal_alignment = 512; + vertical_alignment = 8; + } else { + horizontal_alignment = 128; + vertical_alignment = 32; } break; } - if (i915_dev->gen > 3) { - *width = ALIGN(*width, width_alignment); - *height = ALIGN(*height, height_alignment); + *aligned_height = ALIGN(bo->height, vertical_alignment); + if (i915->gen > 3) { + *stride = ALIGN(*stride, horizontal_alignment); } else { - uint32_t w; - for (w = width_alignment; w < *width; w <<= 1) - ; - *width = w; - *height = ALIGN(*height, height_alignment); + while (*stride > horizontal_alignment) + horizontal_alignment <<= 1; + + *stride = horizontal_alignment; } + + if (i915->gen <= 3 && *stride > 8192) + return -EINVAL; + + return 0; } -static int i915_verify_dimensions(struct driver *drv, uint32_t stride, - uint32_t height) +static void i915_clflush(void *start, size_t size) { - struct i915_device *i915_dev = (struct i915_device *)drv->priv; - if (i915_dev->gen <= 3 && stride > 8192) - return 0; + void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK); + void *end = (void *)((uintptr_t)start + size); - return 1; + __builtin_ia32_mfence(); + while (p < end) { + __builtin_ia32_clflush(p); + p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE); + } } static int i915_init(struct driver *drv) { - struct i915_device *i915_dev; - drm_i915_getparam_t get_param; - int device_id; int ret; + int device_id; + struct i915_device *i915; + drm_i915_getparam_t get_param; - i915_dev = calloc(1, sizeof(*i915_dev)); - if (!i915_dev) - return -1; + i915 = calloc(1, sizeof(*i915)); + if (!i915) + return -ENOMEM; memset(&get_param, 0, sizeof(get_param)); get_param.param = I915_PARAM_CHIPSET_ID; get_param.value = &device_id; ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GETPARAM failed\n"); - free(i915_dev); + fprintf(stderr, "drv: Failed to get I915_PARAM_CHIPSET_ID\n"); + free(i915); return -EINVAL; } - i915_dev->gen = get_gen(device_id); - i915_dev->count = 0; + i915->gen = i915_get_gen(device_id); - i915_dev->mgr = drm_intel_bufmgr_gem_init(drv->fd, 16 * 1024); - if (!i915_dev->mgr) { - fprintf(stderr, "drv: drm_intel_bufmgr_gem_init failed\n"); - free(i915_dev); + memset(&get_param, 0, sizeof(get_param)); + get_param.param = I915_PARAM_HAS_LLC; + get_param.value = &i915->has_llc; + ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param); + if (ret) { + fprintf(stderr, "drv: Failed to get I915_PARAM_HAS_LLC\n"); + free(i915); return -EINVAL; } - drv->priv = i915_dev; + drv->priv = i915; - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + return i915_add_combinations(drv); } -static void i915_close(struct driver *drv) -{ - struct i915_device *i915_dev = drv->priv; - drm_intel_bufmgr_destroy(i915_dev->mgr); - free(i915_dev); - drv->priv = NULL; -} - -static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { int ret; size_t plane; - char name[20]; - uint32_t tiling_mode; - struct i915_bo *i915_bo; - - int bpp = drv_stride_from_format(format, 1, 0); - struct i915_device *i915_dev = (struct i915_device *)bo->drv->priv; + uint32_t stride; + struct drm_i915_gem_create gem_create; + struct drm_i915_gem_set_tiling gem_set_tiling; - if (flags & (BO_USE_CURSOR | BO_USE_LINEAR | - BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) - tiling_mode = I915_TILING_NONE; + if (flags & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) + bo->tiling = I915_TILING_NONE; else if (flags & BO_USE_SCANOUT) - tiling_mode = I915_TILING_X; + bo->tiling = I915_TILING_X; else - tiling_mode = I915_TILING_Y; + bo->tiling = I915_TILING_Y; - i915_align_dimensions(bo->drv, tiling_mode, &width, &height, bpp); - drv_bo_from_format(bo, width, height, format); + if (format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID) + bo->tiling = I915_TILING_NONE; - if (!i915_verify_dimensions(bo->drv, bo->strides[0], height)) - return -EINVAL; + stride = drv_stride_from_format(format, width, 0); - snprintf(name, sizeof(name), "i915-buffer-%u", i915_dev->count); - i915_dev->count++; + ret = i915_align_dimensions(bo, bo->tiling, &stride, &height); + if (ret) + return ret; - i915_bo = calloc(1, sizeof(*i915_bo)); - if (!i915_bo) - return -ENOMEM; + /* + * Align the Y plane to 128 bytes so the chroma planes would be aligned + * to 64 byte boundaries. This is an Intel HW requirement. + */ + if (format == DRM_FORMAT_YVU420) + stride = ALIGN(stride, 128); - bo->priv = i915_bo; + /* + * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. + */ + if (format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; - i915_bo->ibos[0] = drm_intel_bo_alloc(i915_dev->mgr, name, - bo->total_size, 0); - if (!i915_bo->ibos[0]) { - fprintf(stderr, "drv: drm_intel_bo_alloc failed"); - free(i915_bo); - bo->priv = NULL; - return -ENOMEM; - } + drv_bo_from_format(bo, stride, height, format); - for (plane = 0; plane < bo->num_planes; plane++) { - if (plane > 0) - drm_intel_bo_reference(i915_bo->ibos[0]); + memset(&gem_create, 0, sizeof(gem_create)); + gem_create.size = bo->total_size; - bo->handles[plane].u32 = i915_bo->ibos[0]->handle; - i915_bo->ibos[plane] = i915_bo->ibos[0]; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", + gem_create.size); + return ret; } - bo->tiling = tiling_mode; + for (plane = 0; plane < bo->num_planes; plane++) + bo->handles[plane].u32 = gem_create.handle; + + memset(&gem_set_tiling, 0, sizeof(gem_set_tiling)); + gem_set_tiling.handle = bo->handles[0].u32; + gem_set_tiling.tiling_mode = bo->tiling; + gem_set_tiling.stride = bo->strides[0]; - ret = drm_intel_bo_set_tiling(i915_bo->ibos[0], &bo->tiling, - bo->strides[0]); + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling); + if (ret) { + struct drm_gem_close gem_close; + memset(&gem_close, 0, sizeof(gem_close)); + gem_close.handle = bo->handles[0].u32; + drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); - if (ret || bo->tiling != tiling_mode) { - fprintf(stderr, "drv: drm_intel_gem_bo_set_tiling failed " - "errno=%x, stride=%x\n", errno, bo->strides[0]); - /* Calls i915 bo destroy. */ - bo->drv->backend->bo_destroy(bo); + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_TILING failed with %d", errno); return -errno; } return 0; } -static int i915_bo_destroy(struct bo *bo) +static void i915_close(struct driver *drv) { - size_t plane; - struct i915_bo *i915_bo = bo->priv; - - for (plane = 0; plane < bo->num_planes; plane++) - drm_intel_bo_unreference(i915_bo->ibos[plane]); - - free(i915_bo); - bo->priv = NULL; - - return 0; + free(drv->priv); + drv->priv = NULL; } static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data) { - size_t plane; - uint32_t swizzling; - struct i915_bo *i915_bo; - struct i915_device *i915_dev = bo->drv->priv; - - i915_bo = calloc(1, sizeof(*i915_bo)); - if (!i915_bo) - return -ENOMEM; - - bo->priv = i915_bo; + int ret; + struct drm_i915_gem_get_tiling gem_get_tiling; - /* - * When self-importing, libdrm_intel increments the reference count - * on the drm_intel_bo. It also returns the same drm_intel_bo per GEM - * handle. Thus, we don't need to increase the reference count - * (i.e, drv_increment_reference_count) when importing with this - * backend. - */ - for (plane = 0; plane < bo->num_planes; plane++) { - - i915_bo->ibos[plane] = drm_intel_bo_gem_create_from_prime(i915_dev->mgr, - data->fds[plane], data->sizes[plane]); - - if (!i915_bo->ibos[plane]) { - /* - * Need to call GEM close on planes that were opened, - * if any. Adjust the num_planes variable to be the - * plane that failed, so GEM close will be called on - * planes before that plane. - */ - bo->num_planes = plane; - i915_bo_destroy(bo); - fprintf(stderr, "drv: i915: failed to import failed"); - return -EINVAL; - } + ret = drv_prime_bo_import(bo, data); + if (ret) + return ret; - bo->handles[plane].u32 = i915_bo->ibos[plane]->handle; - } + /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */ + memset(&gem_get_tiling, 0, sizeof(gem_get_tiling)); + gem_get_tiling.handle = bo->handles[0].u32; - if (drm_intel_bo_get_tiling(i915_bo->ibos[0], &bo->tiling, - &swizzling)) { - fprintf(stderr, "drv: drm_intel_bo_get_tiling failed"); - i915_bo_destroy(bo); - return -EINVAL; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_GET_TILING failed."); + return ret; } + bo->tiling = gem_get_tiling.tiling_mode; return 0; } static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane) { int ret; - struct i915_bo *i915_bo = bo->priv; + void *addr; + struct drm_i915_gem_set_domain set_domain; + + memset(&set_domain, 0, sizeof(set_domain)); + set_domain.handle = bo->handles[0].u32; + if (bo->tiling == I915_TILING_NONE) { + struct drm_i915_gem_mmap gem_map; + memset(&gem_map, 0, sizeof(gem_map)); + + gem_map.handle = bo->handles[0].u32; + gem_map.offset = 0; + gem_map.size = bo->total_size; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_MMAP failed\n"); + return MAP_FAILED; + } - if (bo->tiling == I915_TILING_NONE) - /* TODO(gsingh): use bo_map flags to determine if we should - * enable writing. - */ - ret = drm_intel_bo_map(i915_bo->ibos[0], 1); - else - ret = drm_intel_gem_bo_map_gtt(i915_bo->ibos[0]); + addr = (void *)(uintptr_t)gem_map.addr_ptr; + set_domain.read_domains = I915_GEM_DOMAIN_CPU; + set_domain.write_domain = I915_GEM_DOMAIN_CPU; + + } else { + struct drm_i915_gem_mmap_gtt gem_map; + memset(&gem_map, 0, sizeof(gem_map)); + + gem_map.handle = bo->handles[0].u32; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_MMAP_GTT failed\n"); + return MAP_FAILED; + } + + addr = mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + gem_map.offset); + + set_domain.read_domains = I915_GEM_DOMAIN_GTT; + set_domain.write_domain = I915_GEM_DOMAIN_GTT; + } + + if (addr == MAP_FAILED) { + fprintf(stderr, "drv: i915 GEM mmap failed\n"); + return addr; + } + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); if (ret) { - fprintf(stderr, "drv: i915_bo_map failed."); + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_DOMAIN failed\n"); return MAP_FAILED; } - return i915_bo->ibos[0]->virtual; + data->length = bo->total_size; + return addr; } static int i915_bo_unmap(struct bo *bo, struct map_info *data) { - int ret; - struct i915_bo *i915_bo = bo->priv; + struct i915_device *i915 = bo->drv->priv; + if (!i915->has_llc && bo->tiling == I915_TILING_NONE) + i915_clflush(data->addr, data->length); - if (bo->tiling == I915_TILING_NONE) - ret = drm_intel_bo_unmap(i915_bo->ibos[0]); - else - ret = drm_intel_gem_bo_unmap_gtt(i915_bo->ibos[0]); - - return ret; + return munmap(data->addr, data->length); } static uint32_t i915_resolve_format(uint32_t format) @@ -357,13 +439,12 @@ static uint32_t i915_resolve_format(uint32_t format) } } -struct backend backend_i915 = -{ +struct backend backend_i915 = { .name = "i915", .init = i915_init, .close = i915_close, .bo_create = i915_bo_create, - .bo_destroy = i915_bo_destroy, + .bo_destroy = drv_gem_bo_destroy, .bo_import = i915_bo_import, .bo_map = i915_bo_map, .bo_unmap = i915_bo_unmap, diff --git a/chromium/third_party/minigbm/src/list.h b/chromium/third_party/minigbm/src/list.h deleted file mode 100644 index 53f46e7ffc1..00000000000 --- a/chromium/third_party/minigbm/src/list.h +++ /dev/null @@ -1,247 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 VMware, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -/** - * \file - * List macros heavily inspired by the Linux kernel - * list handling. No list looping yet. - * - * Is not threadsafe, so common operations need to - * be protected using an external mutex. - */ - -#ifndef _UTIL_LIST_H_ -#define _UTIL_LIST_H_ - - -#include <stdbool.h> -#include <stddef.h> -#include <assert.h> - - -struct list_head -{ - struct list_head *prev; - struct list_head *next; -}; - -static inline void list_inithead(struct list_head *item) -{ - item->prev = item; - item->next = item; -} - -static inline void list_add(struct list_head *item, struct list_head *list) -{ - item->prev = list; - item->next = list->next; - list->next->prev = item; - list->next = item; -} - -static inline void list_addtail(struct list_head *item, struct list_head *list) -{ - item->next = list; - item->prev = list->prev; - list->prev->next = item; - list->prev = item; -} - -static inline bool list_empty(struct list_head *list); - -static inline void list_replace(struct list_head *from, struct list_head *to) -{ - if (list_empty(from)) { - list_inithead(to); - } else { - to->prev = from->prev; - to->next = from->next; - from->next->prev = to; - from->prev->next = to; - } -} - -static inline void list_del(struct list_head *item) -{ - item->prev->next = item->next; - item->next->prev = item->prev; - item->prev = item->next = NULL; -} - -static inline void list_delinit(struct list_head *item) -{ - item->prev->next = item->next; - item->next->prev = item->prev; - item->next = item; - item->prev = item; -} - -static inline bool list_empty(struct list_head *list) -{ - return list->next == list; -} - -/** - * Returns whether the list has exactly one element. - */ -static inline bool list_is_singular(const struct list_head *list) -{ - return list->next != NULL && list->next->next == list; -} - -static inline unsigned list_length(struct list_head *list) -{ - struct list_head *node; - unsigned length = 0; - for (node = list->next; node != list; node = node->next) - length++; - return length; -} - -static inline void list_splice(struct list_head *src, struct list_head *dst) -{ - if (list_empty(src)) - return; - - src->next->prev = dst; - src->prev->next = dst->next; - dst->next->prev = src->prev; - dst->next = src->next; -} - -static inline void list_splicetail(struct list_head *src, struct list_head *dst) -{ - if (list_empty(src)) - return; - - src->prev->next = dst; - src->next->prev = dst->prev; - dst->prev->next = src->next; - dst->prev = src->prev; -} - -static inline void list_validate(struct list_head *list) -{ - struct list_head *node; - assert(list->next->prev == list && list->prev->next == list); - for (node = list->next; node != list; node = node->next) - assert(node->next->prev == node && node->prev->next == node); -} - -#define LIST_INITHEAD(__item) list_inithead(__item) -#define LIST_ADD(__item, __list) list_add(__item, __list) -#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list) -#define LIST_REPLACE(__from, __to) list_replace(__from, __to) -#define LIST_DEL(__item) list_del(__item) -#define LIST_DELINIT(__item) list_delinit(__item) - -#define LIST_ENTRY(__type, __item, __field) \ - ((__type *)(void *)(((char *)(__item)) - offsetof(__type, __field))) - -#define LIST_IS_EMPTY(__list) \ - ((__list)->next == (__list)) - -/** - * Cast from a pointer to a member of a struct back to the containing struct. - * - * 'sample' MUST be initialized, or else the result is undefined! - */ -#ifndef container_of -#define container_of(ptr, sample, member) \ - (void *)((char *)(ptr) \ - - ((char *)&(sample)->member - (char *)(sample))) -#endif - -#define list_first_entry(ptr, type, member) \ - LIST_ENTRY(type, (ptr)->next, member) - -#define list_last_entry(ptr, type, member) \ - LIST_ENTRY(type, (ptr)->prev, member) - - -#define LIST_FOR_EACH_ENTRY(pos, head, member) \ - for (pos = NULL, pos = container_of((head)->next, pos, member); \ - &pos->member != (head); \ - pos = container_of(pos->member.next, pos, member)) - -#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ - for (pos = NULL, pos = container_of((head)->next, pos, member), \ - storage = container_of(pos->member.next, pos, member); \ - &pos->member != (head); \ - pos = storage, storage = container_of(storage->member.next, storage, member)) - -#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ - for (pos = NULL, pos = container_of((head)->prev, pos, member), \ - storage = container_of(pos->member.prev, pos, member); \ - &pos->member != (head); \ - pos = storage, storage = container_of(storage->member.prev, storage, member)) - -#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ - for (pos = NULL, pos = container_of((start), pos, member); \ - &pos->member != (head); \ - pos = container_of(pos->member.next, pos, member)) - -#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ - for (pos = NULL, pos = container_of((start), pos, member); \ - &pos->member != (head); \ - pos = container_of(pos->member.prev, pos, member)) - -#define list_for_each_entry(type, pos, head, member) \ - for (type *pos = LIST_ENTRY(type, (head)->next, member); \ - &pos->member != (head); \ - pos = LIST_ENTRY(type, pos->member.next, member)) - -#define list_for_each_entry_safe(type, pos, head, member) \ - for (type *pos = LIST_ENTRY(type, (head)->next, member), \ - *__next = LIST_ENTRY(type, pos->member.next, member); \ - &pos->member != (head); \ - pos = __next, \ - __next = LIST_ENTRY(type, __next->member.next, member)) - -#define list_for_each_entry_rev(type, pos, head, member) \ - for (type *pos = LIST_ENTRY(type, (head)->prev, member); \ - &pos->member != (head); \ - pos = LIST_ENTRY(type, pos->member.prev, member)) - -#define list_for_each_entry_safe_rev(type, pos, head, member) \ - for (type *pos = LIST_ENTRY(type, (head)->prev, member), \ - *__prev = LIST_ENTRY(type, pos->member.prev, member); \ - &pos->member != (head); \ - pos = __prev, \ - __prev = LIST_ENTRY(type, __prev->member.prev, member)) - -#define list_for_each_entry_from(type, pos, start, head, member) \ - for (type *pos = LIST_ENTRY(type, (start), member); \ - &pos->member != (head); \ - pos = LIST_ENTRY(type, pos->member.next, member)) - -#define list_for_each_entry_from_rev(type, pos, start, head, member) \ - for (type *pos = LIST_ENTRY(type, (start), member); \ - &pos->member != (head); \ - pos = LIST_ENTRY(type, pos->member.prev, member)) - -#endif /*_UTIL_LIST_H_*/ diff --git a/chromium/third_party/minigbm/src/marvell.c b/chromium/third_party/minigbm/src/marvell.c index ae3dc4570dc..8114ac7d7ae 100644 --- a/chromium/third_party/minigbm/src/marvell.c +++ b/chromium/third_party/minigbm/src/marvell.c @@ -10,23 +10,21 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[2] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -} +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int marvell_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_add_linear_combinations(drv, render_target_formats, + ARRAY_SIZE(render_target_formats)); } -struct backend backend_marvell = -{ +struct backend backend_marvell = { .name = "marvell", .init = marvell_init, .bo_create = drv_dumb_bo_create, diff --git a/chromium/third_party/minigbm/src/mediatek.c b/chromium/third_party/minigbm/src/mediatek.c index 7e85f63409a..d2e9f53b567 100644 --- a/chromium/third_party/minigbm/src/mediatek.c +++ b/chromium/third_party/minigbm/src/mediatek.c @@ -6,59 +6,64 @@ #ifdef DRV_MEDIATEK +// clang-format off #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <xf86drm.h> #include <mediatek_drm.h> +// clang-format on #include "drv_priv.h" #include "helpers.h" #include "util.h" -static struct supported_combination combos[6] = { - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int mediatek_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { int ret; size_t plane; + uint32_t stride; struct drm_mtk_gem_create gem_create; - drv_bo_from_format(bo, width, height, format); + /* + * Since the ARM L1 cache line size is 64 bytes, align to that as a + * performance optimization. + */ + stride = drv_stride_from_format(format, width, 0); + stride = ALIGN(stride, 64); + drv_bo_from_format(bo, stride, height, format); memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_CREATE failed " - "(size=%llu)\n", gem_create.size); + fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_CREATE failed (size=%llu)\n", + gem_create.size); return ret; } @@ -78,14 +83,14 @@ static void *mediatek_bo_map(struct bo *bo, struct map_info *data, size_t plane) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_MAP_OFFSET, &gem_map); if (ret) { - fprintf(stderr,"drv: DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n"); + fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n"); return MAP_FAILED; } data->length = bo->total_size; - return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, gem_map.offset); + return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + gem_map.offset); } static uint32_t mediatek_resolve_format(uint32_t format) @@ -101,8 +106,7 @@ static uint32_t mediatek_resolve_format(uint32_t format) } } -struct backend backend_mediatek = -{ +struct backend backend_mediatek = { .name = "mediatek", .init = mediatek_init, .bo_create = mediatek_bo_create, diff --git a/chromium/third_party/minigbm/src/nouveau.c b/chromium/third_party/minigbm/src/nouveau.c index e0d5954db72..7cdab3a040d 100644 --- a/chromium/third_party/minigbm/src/nouveau.c +++ b/chromium/third_party/minigbm/src/nouveau.c @@ -8,19 +8,20 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[2] = { - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, BO_USE_CURSOR | BO_USE_RENDERING}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, BO_USE_CURSOR | BO_USE_RENDERING}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int nouveau_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_nouveau = -{ +struct backend backend_nouveau = { .name = "nouveau", .init = nouveau_init, .bo_create = drv_dumb_bo_create, diff --git a/chromium/third_party/minigbm/src/presubmit.sh b/chromium/third_party/minigbm/src/presubmit.sh new file mode 100755 index 00000000000..6d55f2a5e70 --- /dev/null +++ b/chromium/third_party/minigbm/src/presubmit.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# Copyright 2017 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. +find \ + '(' -name '*.[ch]' -or -name '*.cc' ')' \ + -not -name 'gbm.h' \ + -exec clang-format -style=file -i {} + diff --git a/chromium/third_party/minigbm/src/rockchip.c b/chromium/third_party/minigbm/src/rockchip.c index a64a42f682f..50ea4ef7640 100644 --- a/chromium/third_party/minigbm/src/rockchip.c +++ b/chromium/third_party/minigbm/src/rockchip.c @@ -7,47 +7,25 @@ #ifdef DRV_ROCKCHIP #include <errno.h> +#include <rockchip_drm.h> +#include <stdbool.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <xf86drm.h> -#include <rockchip_drm.h> #include "drv_priv.h" #include "helpers.h" #include "util.h" -static struct supported_combination combos[12] = { - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; -static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format) +static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format) { /* We've restricted ourselves to four bytes per pixel. */ const uint32_t pixel_size = 4; @@ -77,10 +55,8 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, * alignement for the body plane. */ const uint32_t body_plane_alignment = 1024; - const uint32_t body_plane_offset = - ALIGN(header_plane_size, body_plane_alignment); - const uint32_t total_size = - body_plane_offset + body_plane_size; + const uint32_t body_plane_offset = ALIGN(header_plane_size, body_plane_alignment); + const uint32_t total_size = body_plane_offset + body_plane_size; bo->strides[0] = width_in_blocks * block_width * pixel_size; bo->sizes[0] = total_size; @@ -93,10 +69,78 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, return 0; } +static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item) +{ + int ret; + uint32_t i, j; + uint64_t flags; + struct combination *combo; + struct format_metadata metadata; + + for (i = 0; i < drv->backend->combos.size; i++) { + combo = &drv->backend->combos.data[i]; + if (combo->format == item->format) { + if (item->modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) { + flags = BO_USE_RENDERING | BO_USE_SCANOUT | BO_USE_TEXTURE; + metadata.modifier = item->modifier; + metadata.tiling = 0; + metadata.priority = 2; + + for (j = 0; j < ARRAY_SIZE(texture_source_formats); j++) { + if (item->format == texture_source_formats[j]) + flags &= ~BO_USE_RENDERING; + } + + ret = drv_add_combination(drv, item[i].format, &metadata, flags); + if (ret) + return ret; + } else { + combo->usage |= item->usage; + } + } + } + + return 0; +} + static int rockchip_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + uint32_t i, num_items; + struct kms_item *items; + struct format_metadata metadata; + + metadata.tiling = 0; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, BO_USE_RENDER_MASK); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + + items = drv_query_kms(drv, &num_items); + if (!items || !num_items) + return 0; + + for (i = 0; i < num_items; i++) { + ret = rockchip_add_kms_item(drv, &items[i]); + if (ret) { + free(items); + return ret; + } + } + + free(items); + return 0; } static bool has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier) @@ -110,10 +154,8 @@ static bool has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier return false; } -static int rockchip_bo_create_with_modifiers(struct bo *bo, - uint32_t width, uint32_t height, - uint32_t format, - const uint64_t *modifiers, +static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count) { int ret; @@ -122,17 +164,15 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, if (format == DRM_FORMAT_NV12) { uint32_t w_mbs = DIV_ROUND_UP(ALIGN(width, 16), 16); - uint32_t h_mbs = DIV_ROUND_UP(ALIGN(width, 16), 16); + uint32_t h_mbs = DIV_ROUND_UP(ALIGN(height, 16), 16); uint32_t aligned_width = w_mbs * 16; uint32_t aligned_height = DIV_ROUND_UP(h_mbs * 16 * 3, 2); drv_bo_from_format(bo, aligned_width, height, format); - bo->total_size = bo->strides[0] * aligned_height - + w_mbs * h_mbs * 128; + bo->total_size = bo->strides[0] * aligned_height + w_mbs * h_mbs * 128; } else if (width <= 2560 && - has_modifier(modifiers, count, - DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { + has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { /* If the caller has decided they can use AFBC, always * pick that */ afbc_bo_from_format(bo, width, height, format); @@ -142,18 +182,31 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, fprintf(stderr, "no usable modifier found\n"); return -1; } - drv_bo_from_format(bo, width, height, format); + + uint32_t stride; + /* + * Since the ARM L1 cache line size is 64 bytes, align to that + * as a performance optimization. For YV12, the Mali cmem allocator + * requires that chroma planes are aligned to 64-bytes, so align the + * luma plane to 128 bytes. + */ + stride = drv_stride_from_format(format, width, 0); + if (format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID) + stride = ALIGN(stride, 128); + else + stride = ALIGN(stride, 64); + + drv_bo_from_format(bo, stride, height, format); } memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->total_size; - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, - &gem_create); + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed " - "(size=%llu)\n", gem_create.size); + fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", + gem_create.size); return ret; } @@ -163,13 +216,13 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, return 0; } -static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { uint64_t modifiers[] = { DRM_FORMAT_MOD_NONE }; - return rockchip_bo_create_with_modifiers(bo, width, height, format, - modifiers, ARRAY_SIZE(modifiers)); + return rockchip_bo_create_with_modifiers(bo, width, height, format, modifiers, + ARRAY_SIZE(modifiers)); } static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane) @@ -185,18 +238,16 @@ static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane) memset(&gem_map, 0, sizeof(gem_map)); gem_map.handle = bo->handles[0].u32; - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, - &gem_map); + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &gem_map); if (ret) { - fprintf(stderr, - "drv: DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n"); + fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n"); return MAP_FAILED; } data->length = bo->total_size; - return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, gem_map.offset); + return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + gem_map.offset); } static uint32_t rockchip_resolve_format(uint32_t format) @@ -212,8 +263,7 @@ static uint32_t rockchip_resolve_format(uint32_t format) } } -struct backend backend_rockchip = -{ +struct backend backend_rockchip = { .name = "rockchip", .init = rockchip_init, .bo_create = rockchip_bo_create, diff --git a/chromium/third_party/minigbm/src/tegra.c b/chromium/third_party/minigbm/src/tegra.c index f48352e615d..09ca8b2372e 100644 --- a/chromium/third_party/minigbm/src/tegra.c +++ b/chromium/third_party/minigbm/src/tegra.c @@ -6,11 +6,12 @@ #ifdef DRV_TEGRA +#include <assert.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> -#include <xf86drm.h> #include <tegra_drm.h> +#include <xf86drm.h> #include "drv_priv.h" #include "helpers.h" @@ -26,6 +27,7 @@ #define NV_DEFAULT_BLOCK_HEIGHT_LOG2 4 #define NV_PREFERRED_PAGE_SIZE (128 * 1024) +// clang-format off enum nv_mem_kind { NV_MEM_KIND_PITCH = 0, @@ -37,22 +39,14 @@ enum tegra_map_type { TEGRA_READ_TILED_BUFFER = 0, TEGRA_WRITE_TILED_BUFFER = 1, }; +// clang-format on struct tegra_private_map_data { void *tiled; void *untiled; }; -static struct supported_combination combos[4] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int compute_block_height_log2(int height) { @@ -72,10 +66,9 @@ static int compute_block_height_log2(int height) return block_height_log2; } -static void compute_layout_blocklinear(int width, int height, int format, - enum nv_mem_kind *kind, - uint32_t *block_height_log2, - uint32_t *stride, uint32_t *size) +static void compute_layout_blocklinear(int width, int height, int format, enum nv_mem_kind *kind, + uint32_t *block_height_log2, uint32_t *stride, + uint32_t *size) { int pitch = drv_stride_from_format(format, width, 0); @@ -85,8 +78,7 @@ static void compute_layout_blocklinear(int width, int height, int format, /* Compute padded height. */ *block_height_log2 = compute_block_height_log2(height); int block_height = 1 << *block_height_log2; - int padded_height = - ALIGN(height, NV_BLOCKLINEAR_GOB_HEIGHT * block_height); + int padded_height = ALIGN(height, NV_BLOCKLINEAR_GOB_HEIGHT * block_height); int bytes = pitch * padded_height; @@ -101,16 +93,15 @@ static void compute_layout_blocklinear(int width, int height, int format, *size = bytes; } -static void compute_layout_linear(int width, int height, int format, - uint32_t *stride, uint32_t *size) +static void compute_layout_linear(int width, int height, int format, uint32_t *stride, + uint32_t *size) { *stride = ALIGN(drv_stride_from_format(format, width, 0), 64); *size = *stride * height; } -static void transfer_tile(struct bo *bo, uint8_t *tiled, uint8_t *untiled, - enum tegra_map_type type, uint32_t bytes_per_pixel, - uint32_t gob_top, uint32_t gob_left, +static void transfer_tile(struct bo *bo, uint8_t *tiled, uint8_t *untiled, enum tegra_map_type type, + uint32_t bytes_per_pixel, uint32_t gob_top, uint32_t gob_left, uint32_t gob_size_pixels) { uint8_t *tmp; @@ -136,11 +127,11 @@ static void transfer_tile(struct bo *bo, uint8_t *tiled, uint8_t *untiled, } } -static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, - uint8_t *untiled, enum tegra_map_type type) +static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, uint8_t *untiled, + enum tegra_map_type type) { - uint32_t gob_width, gob_height, gob_size_bytes, gob_size_pixels, - gob_count_x, gob_count_y, gob_top, gob_left; + uint32_t gob_width, gob_height, gob_size_bytes, gob_size_pixels, gob_count_x, gob_count_y, + gob_top, gob_left; uint32_t i, j, offset; uint8_t *tmp; uint32_t bytes_per_pixel = drv_stride_from_format(bo->format, 1, 0); @@ -150,11 +141,9 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, * where 0 <= n <= 4. */ gob_width = DIV_ROUND_UP(NV_BLOCKLINEAR_GOB_WIDTH, bytes_per_pixel); - gob_height = NV_BLOCKLINEAR_GOB_HEIGHT * - (1 << NV_DEFAULT_BLOCK_HEIGHT_LOG2); + gob_height = NV_BLOCKLINEAR_GOB_HEIGHT * (1 << NV_DEFAULT_BLOCK_HEIGHT_LOG2); /* Calculate the height from maximum possible gob height */ - while (gob_height > NV_BLOCKLINEAR_GOB_HEIGHT - && gob_height >= 2 * bo->height) + while (gob_height > NV_BLOCKLINEAR_GOB_HEIGHT && gob_height >= 2 * bo->height) gob_height /= 2; gob_size_bytes = gob_height * NV_BLOCKLINEAR_GOB_WIDTH; @@ -170,8 +159,8 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, tmp = tiled + offset; gob_left = i * gob_width; - transfer_tile(bo, tmp, untiled, type, bytes_per_pixel, - gob_top, gob_left, gob_size_pixels); + transfer_tile(bo, tmp, untiled, type, bytes_per_pixel, gob_top, gob_left, + gob_size_pixels); offset += gob_size_bytes; } @@ -180,23 +169,52 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, static int tegra_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + struct format_metadata metadata; + uint64_t flags = BO_USE_RENDER_MASK; + + metadata.tiling = NV_MEM_KIND_PITCH; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + + flags &= ~BO_USE_SW_WRITE_OFTEN; + flags &= ~BO_USE_SW_READ_OFTEN; + flags &= ~BO_USE_LINEAR; + + metadata.tiling = NV_MEM_KIND_C32_2CRA; + metadata.priority = 2; + + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, flags); + if (ret) + return ret; + + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_SCANOUT); + return 0; } -static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { uint32_t size, stride, block_height_log2 = 0; enum nv_mem_kind kind = NV_MEM_KIND_PITCH; struct drm_tegra_gem_create gem_create; int ret; - if (flags & BO_USE_RENDERING) - compute_layout_blocklinear(width, height, format, &kind, - &block_height_log2, &stride, &size); - else + if (flags & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) compute_layout_linear(width, height, format, &stride, &size); + else + compute_layout_blocklinear(width, height, format, &kind, &block_height_log2, + &stride, &size); memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = size; @@ -204,8 +222,7 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_TEGRA_GEM_CREATE failed " - "(size=%zu)\n", size); + fprintf(stderr, "drv: DRM_IOCTL_TEGRA_GEM_CREATE failed (size=%zu)\n", size); return ret; } @@ -222,16 +239,15 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, gem_tile.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK; gem_tile.value = block_height_log2; - ret = drmCommandWriteRead(bo->drv->fd, DRM_TEGRA_GEM_SET_TILING, - &gem_tile, sizeof(gem_tile)); + ret = drmCommandWriteRead(bo->drv->fd, DRM_TEGRA_GEM_SET_TILING, &gem_tile, + sizeof(gem_tile)); if (ret < 0) { drv_gem_bo_destroy(bo); return ret; } /* Encode blocklinear parameters for EGLImage creation. */ - bo->tiling = (kind & 0xff) | - ((block_height_log2 & 0xf) << 8); + bo->tiling = (kind & 0xff) | ((block_height_log2 & 0xf) << 8); bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); } @@ -247,25 +263,22 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane) memset(&gem_map, 0, sizeof(gem_map)); gem_map.handle = bo->handles[0].u32; - ret = drmCommandWriteRead(bo->drv->fd, DRM_TEGRA_GEM_MMAP, &gem_map, - sizeof(gem_map)); + ret = drmCommandWriteRead(bo->drv->fd, DRM_TEGRA_GEM_MMAP, &gem_map, sizeof(gem_map)); if (ret < 0) { fprintf(stderr, "drv: DRM_TEGRA_GEM_MMAP failed\n"); return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, gem_map.offset); + void *addr = mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + gem_map.offset); data->length = bo->total_size; - if ((bo->tiling & 0xFF) == NV_MEM_KIND_C32_2CRA && addr != MAP_FAILED) { priv = calloc(1, sizeof(*priv)); priv->untiled = calloc(1, bo->total_size); priv->tiled = addr; data->priv = priv; - transfer_tiled_memory(bo, priv->tiled, priv->untiled, - TEGRA_READ_TILED_BUFFER); + transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_READ_TILED_BUFFER); addr = priv->untiled; } @@ -276,8 +289,7 @@ static int tegra_bo_unmap(struct bo *bo, struct map_info *data) { if (data->priv) { struct tegra_private_map_data *priv = data->priv; - transfer_tiled_memory(bo, priv->tiled, priv->untiled, - TEGRA_WRITE_TILED_BUFFER); + transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_WRITE_TILED_BUFFER); data->addr = priv->tiled; free(priv->untiled); free(priv); @@ -287,13 +299,47 @@ static int tegra_bo_unmap(struct bo *bo, struct map_info *data) return munmap(data->addr, data->length); } -struct backend backend_tegra = +static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) { + int ret; + struct drm_tegra_gem_get_tiling gem_get_tiling; + + ret = drv_prime_bo_import(bo, data); + if (ret) + return ret; + + /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */ + memset(&gem_get_tiling, 0, sizeof(gem_get_tiling)); + gem_get_tiling.handle = bo->handles[0].u32; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_GET_TILING, &gem_get_tiling); + if (ret) { + drv_gem_bo_destroy(bo); + return ret; + } + + /* NOTE(djmk): we only know about one tiled format, so if our drmIoctl call tells us we are + tiled, assume it is this format (NV_MEM_KIND_C32_2CRA) otherwise linear (KIND_PITCH). */ + if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_PITCH) { + bo->tiling = NV_MEM_KIND_PITCH; + } else if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_BLOCK) { + bo->tiling = NV_MEM_KIND_C32_2CRA; + } else { + fprintf(stderr, "tegra_bo_import: unknown tile format %d", gem_get_tiling.mode); + drv_gem_bo_destroy(bo); + assert(0); + } + + bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); + return 0; +} + +struct backend backend_tegra = { .name = "tegra", .init = tegra_init, .bo_create = tegra_bo_create, .bo_destroy = drv_gem_bo_destroy, - .bo_import = drv_prime_bo_import, + .bo_import = tegra_bo_import, .bo_map = tegra_bo_map, .bo_unmap = tegra_bo_unmap, }; diff --git a/chromium/third_party/minigbm/src/udl.c b/chromium/third_party/minigbm/src/udl.c index c607772b736..eb15fbeb461 100644 --- a/chromium/third_party/minigbm/src/udl.c +++ b/chromium/third_party/minigbm/src/udl.c @@ -8,23 +8,20 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[2] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int udl_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_udl = -{ +struct backend backend_udl = { .name = "udl", .init = udl_init, .bo_create = drv_dumb_bo_create, diff --git a/chromium/third_party/minigbm/src/util.h b/chromium/third_party/minigbm/src/util.h index 696b996b9af..fd61d9b4b61 100644 --- a/chromium/third_party/minigbm/src/util.h +++ b/chromium/third_party/minigbm/src/util.h @@ -8,9 +8,9 @@ #define UTIL_H #define MAX(A, B) ((A) > (B) ? (A) : (B)) -#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*(A))) +#define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) #define PUBLIC __attribute__((visibility("default"))) -#define ALIGN(A, B) (((A) + (B) - 1) / (B) * (B)) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define ALIGN(A, B) (((A) + (B)-1) / (B) * (B)) +#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) #endif diff --git a/chromium/third_party/minigbm/src/vc4.c b/chromium/third_party/minigbm/src/vc4.c index 7e5351f2775..99896b9b772 100644 --- a/chromium/third_party/minigbm/src/vc4.c +++ b/chromium/third_party/minigbm/src/vc4.c @@ -16,40 +16,43 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[3] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE, - BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888 }; static int vc4_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { int ret; size_t plane; + uint32_t stride; struct drm_vc4_create_bo bo_create; - drv_bo_from_format(bo, width, height, format); + /* + * Since the ARM L1 cache line size is 64 bytes, align to that as a + * performance optimization. + */ + stride = drv_stride_from_format(format, width, 0); + stride = ALIGN(stride, 64); + drv_bo_from_format(bo, stride, height, format); memset(&bo_create, 0, sizeof(bo_create)); bo_create.size = bo->total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_VC4_GEM_CREATE failed " - "(size=%zu)\n", bo->total_size); + fprintf(stderr, "drv: DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", + bo->total_size); return ret; } @@ -67,8 +70,7 @@ static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane) memset(&bo_map, 0, sizeof(bo_map)); bo_map.handle = bo->handles[0].u32; - ret = drmCommandWriteRead(bo->drv->fd, DRM_VC4_MMAP_BO, &bo_map, - sizeof(bo_map)); + ret = drmCommandWriteRead(bo->drv->fd, DRM_VC4_MMAP_BO, &bo_map, sizeof(bo_map)); if (ret) { fprintf(stderr, "drv: DRM_VC4_MMAP_BO failed\n"); return MAP_FAILED; @@ -76,12 +78,11 @@ static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane) data->length = bo->total_size; - return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->drv->fd, bo_map.offset); + return mmap(0, bo->total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, + bo_map.offset); } -struct backend backend_vc4 = -{ +struct backend backend_vc4 = { .name = "vc4", .init = vc4_init, .bo_create = vc4_bo_create, diff --git a/chromium/third_party/minigbm/src/vgem.c b/chromium/third_party/minigbm/src/vgem.c index 0f3d2e3e0e3..9bf5b878571 100644 --- a/chromium/third_party/minigbm/src/vgem.c +++ b/chromium/third_party/minigbm/src/vgem.c @@ -11,37 +11,40 @@ #define MESA_LLVMPIPE_TILE_ORDER 6 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) -static struct supported_combination combos[4] = { - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE, - BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int vgem_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return 0; + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) +static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { - int ret = drv_dumb_bo_create(bo, ALIGN(width, MESA_LLVMPIPE_TILE_SIZE), - ALIGN(height, MESA_LLVMPIPE_TILE_SIZE), - format, flags); - bo->width = width; - bo->height = height; + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - return ret; + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + return drv_dumb_bo_create(bo, width, height, format, flags); } static uint32_t vgem_resolve_format(uint32_t format) @@ -57,8 +60,7 @@ static uint32_t vgem_resolve_format(uint32_t format) } } -struct backend backend_vgem = -{ +struct backend backend_vgem = { .name = "vgem", .init = vgem_init, .bo_create = vgem_bo_create, @@ -67,4 +69,3 @@ struct backend backend_vgem = .bo_map = drv_dumb_bo_map, .resolve_format = vgem_resolve_format, }; - diff --git a/chromium/third_party/minigbm/src/virtio_gpu.c b/chromium/third_party/minigbm/src/virtio_gpu.c index 5ac0e314aa0..ab1d8f10ec4 100644 --- a/chromium/third_party/minigbm/src/virtio_gpu.c +++ b/chromium/third_party/minigbm/src/virtio_gpu.c @@ -8,28 +8,64 @@ #include "helpers.h" #include "util.h" -static struct supported_combination combos[2] = { - {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, - {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, - BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY}, -}; +#define MESA_LLVMPIPE_TILE_ORDER 6 +#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) + +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int virtio_gpu_init(struct driver *drv) { - drv_insert_combinations(drv, combos, ARRAY_SIZE(combos)); - return drv_add_kms_flags(drv); + int ret; + ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + if (ret) + return ret; + + ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + if (ret) + return ret; + + return drv_modify_linear_combinations(drv); } -struct backend backend_virtio_gpu = +static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint32_t flags) { + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + return drv_dumb_bo_create(bo, width, height, format, flags); +} + +static uint32_t virtio_gpu_resolve_format(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /*HACK: See b/28671744 */ + return DRM_FORMAT_XBGR8888; + case DRM_FORMAT_FLEX_YCbCr_420_888: + return DRM_FORMAT_YVU420; + default: + return format; + } +} + +struct backend backend_virtio_gpu = { .name = "virtio_gpu", .init = virtio_gpu_init, - .bo_create = drv_dumb_bo_create, + .bo_create = virtio_gpu_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .resolve_format = virtio_gpu_resolve_format, }; - |