summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:00:38 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:00:38 +0000
commit2fd64cad52d2ded3ec1f39309608aa73dfe6c8e4 (patch)
tree6e875bc030bdfb362f5851eb8bde03d87e82d935
parent9f5a22cfcb2cc23f3ef8ecbe73b76a2c34382ffb (diff)
parent9b05077bc12b7b13ad680bfaec35ddd3cff5dd93 (diff)
downloadminigbm-aml_cbr_341610000.tar.gz
Change-Id: I66e7dda0ad65e2641cd8ed9bedbc850308344fe5
-rw-r--r--DIR_METADATA34
-rw-r--r--Makefile1
-rw-r--r--amdgpu.c93
-rw-r--r--cros_gralloc/Makefile2
-rw-r--r--cros_gralloc/aidl/Allocator.cpp85
-rw-r--r--cros_gralloc/aidl/Allocator.h8
-rw-r--r--cros_gralloc/aidl/Android.bp18
-rw-r--r--cros_gralloc/aidl/allocator.rc2
-rw-r--r--cros_gralloc/aidl/allocator.xml2
-rw-r--r--cros_gralloc/cros_gralloc_buffer.cc23
-rw-r--r--cros_gralloc/cros_gralloc_buffer.h1
-rw-r--r--cros_gralloc/cros_gralloc_driver.cc96
-rw-r--r--cros_gralloc/cros_gralloc_driver.h3
-rw-r--r--cros_gralloc/cros_gralloc_helpers.cc19
-rw-r--r--cros_gralloc/cros_gralloc_helpers.h4
-rw-r--r--cros_gralloc/gralloc0/gralloc0.cc20
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Allocator.cc16
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Mapper.cc189
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Utils.cc13
-rw-r--r--cros_gralloc/mapper_stablec/.clang-format19
-rw-r--r--cros_gralloc/mapper_stablec/Android.bp44
-rw-r--r--cros_gralloc/mapper_stablec/Mapper.cpp745
-rw-r--r--cros_gralloc/mapper_stablec/mapper.minigbm.xml9
-rw-r--r--dri.c26
-rw-r--r--dri.h3
-rw-r--r--drv.c105
-rw-r--r--drv.h28
-rw-r--r--drv_helpers.c65
-rw-r--r--drv_helpers.h10
-rw-r--r--drv_priv.h15
-rw-r--r--dumb_driver.c17
-rw-r--r--external/i915_drm.h3
-rw-r--r--gbm.h15
-rw-r--r--gbm_helpers.c4
-rw-r--r--i915.c359
-rw-r--r--mediatek.c83
-rw-r--r--minigbm_helpers.c63
-rw-r--r--minigbm_helpers.h8
-rw-r--r--msm.c49
-rw-r--r--rockchip.c17
-rw-r--r--vc4.c10
-rw-r--r--virtgpu.c2
-rw-r--r--virtgpu_cross_domain.c114
-rw-r--r--virtgpu_virgl.c138
44 files changed, 2018 insertions, 562 deletions
diff --git a/DIR_METADATA b/DIR_METADATA
new file mode 100644
index 0000000..55fd9f0
--- /dev/null
+++ b/DIR_METADATA
@@ -0,0 +1,34 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+buganizer {
+ # ChromeOS > Platform > Graphics > Graphics Virtualization
+ component_id: 964076
+}
+
+chromeos {
+ cq {
+ source_test_plans {
+ test_plan_starlark_files {
+ host: "chrome-internal.googlesource.com"
+ project: "chromeos/config-internal"
+ path: "test/plans/v2/ctpv1_compatible/legacy_default_tast_hw.star"
+ }
+ test_plan_starlark_files {
+ host: "chrome-internal.googlesource.com"
+ project: "chromeos/config-internal"
+ path: "test/plans/v2/ctpv1_compatible/legacy_default_autotest_hw.star"
+ }
+ test_plan_starlark_files {
+ host: "chrome-internal.googlesource.com"
+ project: "chromeos/config-internal"
+ path: "test/plans/v2/ctpv1_compatible/legacy_default_vm.star"
+ }
+ }
+ }
+}
diff --git a/Makefile b/Makefile
index 987708f..b45226d 100644
--- a/Makefile
+++ b/Makefile
@@ -59,3 +59,4 @@ install: all
ln -sf $(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)/libgbm.so.$(GBM_VERSION_MAJOR)
install -D -m 0644 $(SRC)/gbm.pc $(DESTDIR)$(LIBDIR)/pkgconfig/gbm.pc
install -D -m 0644 $(SRC)/gbm.h $(DESTDIR)/usr/include/gbm.h
+ install -D -m 0644 $(SRC)/minigbm_helpers.h $(DESTDIR)/usr/include/minigbm/minigbm_helpers.h
diff --git a/amdgpu.c b/amdgpu.c
index 7ff61a4..a3f5e45 100644
--- a/amdgpu.c
+++ b/amdgpu.c
@@ -10,6 +10,7 @@
#include <drm_fourcc.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -278,7 +279,7 @@ static int sdma_copy(struct amdgpu_priv *priv, int fd, uint32_t src_handle, uint
ret = drmCommandWriteRead(fd, DRM_AMDGPU_CS, &cs, sizeof(cs));
if (ret) {
- drv_log("SDMA copy command buffer submission failed %d\n", ret);
+ drv_loge("SDMA copy command buffer submission failed %d\n", ret);
goto unmap_dst;
}
@@ -289,9 +290,9 @@ static int sdma_copy(struct amdgpu_priv *priv, int fd, uint32_t src_handle, uint
ret = drmCommandWriteRead(fd, DRM_AMDGPU_WAIT_CS, &wait_cs, sizeof(wait_cs));
if (ret) {
- drv_log("Could not wait for CS to finish\n");
+ drv_loge("Could not wait for CS to finish\n");
} else if (wait_cs.out.status) {
- drv_log("Infinite wait timed out, likely GPU hang.\n");
+ drv_loge("Infinite wait timed out, likely GPU hang.\n");
ret = -ENODEV;
}
@@ -345,6 +346,18 @@ static bool is_modifier_scanout_capable(struct amdgpu_priv *priv, uint32_t forma
return true;
}
+static void amdgpu_preload(bool load)
+{
+ static void *handle;
+
+ if (load && !handle)
+ handle = dri_dlopen(DRI_PATH);
+ else if (!load && handle) {
+ dri_dlclose(handle);
+ handle = NULL;
+ }
+}
+
static int amdgpu_init(struct driver *drv)
{
struct amdgpu_priv *priv;
@@ -380,7 +393,7 @@ static int amdgpu_init(struct driver *drv)
/* Continue on failure, as we can still succesfully map things without SDMA. */
if (sdma_init(priv, drv_get_fd(drv)))
- drv_log("SDMA init failed\n");
+ drv_loge("SDMA init failed\n");
metadata.tiling = TILE_TYPE_LINEAR;
metadata.priority = 1;
@@ -425,7 +438,8 @@ static int amdgpu_init(struct driver *drv)
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER |
+ BO_USE_SENSOR_DIRECT_DATA);
/*
* The following formats will be allocated by the DRI backend and may be potentially tiled.
@@ -504,26 +518,44 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh
uint64_t use_flags)
{
int ret;
- size_t num_planes;
+ uint32_t stride_align = 1;
uint32_t plane, stride;
union drm_amdgpu_gem_create gem_create = { { 0 } };
struct amdgpu_priv *priv = bo->drv->priv;
stride = drv_stride_from_format(format, width, 0);
- num_planes = drv_num_planes_from_format(format);
- /*
- * For multiplane formats, align the stride to 512 to ensure that subsample strides are 256
- * aligned. This uses more memory than necessary since the first plane only needs to be
- * 256 aligned, but it's acceptable for a short-term fix. It's probably safe for other gpu
- * families, but let's restrict it to Raven and Stoney for now (b/171013552, b/190484589).
- * This only applies to the Android YUV (multiplane) format.
- * */
- if (format == DRM_FORMAT_YVU420_ANDROID &&
- (priv->dev_info.family == AMDGPU_FAMILY_RV || priv->dev_info.family == AMDGPU_FAMILY_CZ))
- stride = ALIGN(stride, 512);
- else
- stride = ALIGN(stride, 256);
+ if (use_flags & BO_USE_HW_MASK) {
+ /* GFX9+ requires the stride to be aligned to 256 bytes */
+ stride_align = 256;
+ stride = ALIGN(stride, stride_align);
+
+ /* Android YV12 requires the UV stride to be half of the Y
+ * stride. Before GFX10, we can double the alignment for the
+ * Y stride, which makes sure the UV stride is still aligned
+ * to 256 bytes after halving.
+ *
+ * GFX10+ additionally requires the stride to be as small as
+ * possible. It is impossible to support the format in some
+ * cases. Instead, we force DRM_FORMAT_YVU420 and knowingly
+ * vioate Android YV12 stride requirement. This is done
+ * because
+ *
+ * - we would like to know what breaks, and
+ * - when used as a classic resource by virglrenderer, the
+ * requirement hopefully does not matter
+ */
+ bool double_align = format == DRM_FORMAT_YVU420_ANDROID;
+ if (double_align && priv->dev_info.family >= AMDGPU_FAMILY_NV &&
+ (use_flags & BO_USE_GPU_HW) && ((stride / stride_align) & 1)) {
+ drv_loge("allocating %dx%d YV12 bo (usage 0x%" PRIx64 ") with bad strides",
+ width, height, use_flags);
+ format = DRM_FORMAT_YVU420;
+ double_align = false;
+ }
+ if (double_align)
+ stride = ALIGN(stride, stride_align * 2);
+ }
/*
* Currently, allocator used by chrome aligns the height for Encoder/
@@ -535,7 +567,7 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh
if (use_flags & (BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER))
height = ALIGN(height, CHROME_HEIGHT_ALIGN);
- drv_bo_from_format(bo, stride, height, format);
+ drv_bo_from_format(bo, stride, stride_align, height, format);
gem_create.in.bo_size =
ALIGN(bo->meta.total_size, priv->dev_info.virtual_address_alignment);
@@ -625,8 +657,8 @@ static int amdgpu_import_bo(struct bo *bo, struct drv_import_fd_data *data)
dri_tiling = combo->metadata.tiling != TILE_TYPE_LINEAR;
}
- bo->meta.num_planes = dri_num_planes_from_modifier(bo->drv, data->format,
- data->format_modifier);
+ bo->meta.num_planes =
+ dri_num_planes_from_modifier(bo->drv, data->format, data->format_modifier);
if (dri_tiling)
return dri_bo_import(bo, data);
@@ -650,19 +682,19 @@ static int amdgpu_destroy_bo(struct bo *bo)
return drv_gem_bo_destroy(bo);
}
-static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
void *addr = MAP_FAILED;
int ret;
union drm_amdgpu_gem_mmap gem_map = { { 0 } };
struct drm_amdgpu_gem_create_in bo_info = { 0 };
struct drm_amdgpu_gem_op gem_op = { 0 };
- uint32_t handle = bo->handles[plane].u32;
+ uint32_t handle = bo->handles[0].u32;
struct amdgpu_linear_vma_priv *priv = NULL;
struct amdgpu_priv *drv_priv;
if (bo->priv)
- return dri_bo_map(bo, vma, plane, map_flags);
+ return dri_bo_map(bo, vma, 0, map_flags);
drv_priv = bo->drv->priv;
gem_op.handle = handle;
@@ -691,7 +723,7 @@ static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_
ret = drmCommandWriteRead(bo->drv->fd, DRM_AMDGPU_GEM_CREATE, &gem_create,
sizeof(gem_create));
if (ret < 0) {
- drv_log("GEM create failed\n");
+ drv_loge("GEM create failed\n");
free(priv);
return MAP_FAILED;
}
@@ -702,7 +734,7 @@ static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_
ret = sdma_copy(bo->drv->priv, bo->drv->fd, bo->handles[0].u32, priv->handle,
bo_info.bo_size);
if (ret) {
- drv_log("SDMA copy for read failed\n");
+ drv_loge("SDMA copy for read failed\n");
goto fail;
}
}
@@ -710,7 +742,7 @@ static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_
gem_map.in.handle = handle;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_AMDGPU_GEM_MMAP failed\n");
+ drv_loge("DRM_IOCTL_AMDGPU_GEM_MMAP failed\n");
goto fail;
}
@@ -775,18 +807,19 @@ static int amdgpu_bo_invalidate(struct bo *bo, struct mapping *mapping)
sizeof(wait_idle));
if (ret < 0) {
- drv_log("DRM_AMDGPU_GEM_WAIT_IDLE failed with %d\n", ret);
+ drv_loge("DRM_AMDGPU_GEM_WAIT_IDLE failed with %d\n", ret);
return ret;
}
if (ret == 0 && wait_idle.out.status)
- drv_log("DRM_AMDGPU_GEM_WAIT_IDLE BO is busy\n");
+ drv_loge("DRM_AMDGPU_GEM_WAIT_IDLE BO is busy\n");
return 0;
}
const struct backend backend_amdgpu = {
.name = "amdgpu",
+ .preload = amdgpu_preload,
.init = amdgpu_init,
.close = amdgpu_close,
.bo_create = amdgpu_create_bo,
diff --git a/cros_gralloc/Makefile b/cros_gralloc/Makefile
index c95ad2c..b0d62d7 100644
--- a/cros_gralloc/Makefile
+++ b/cros_gralloc/Makefile
@@ -9,7 +9,7 @@ SRCS += $(wildcard ../*.c)
SRCS += $(wildcard gralloc0/*.cc)
-SOURCES = $(filter-out ../gbm%, $(SRCS))
+SOURCES = $(filter-out ../gbm% ../minigbm%, $(SRCS))
PKG_CONFIG ?= pkg-config
VPATH = $(dir $(SOURCES))
diff --git a/cros_gralloc/aidl/Allocator.cpp b/cros_gralloc/aidl/Allocator.cpp
index 0d81d5c..2ea5a0d 100644
--- a/cros_gralloc/aidl/Allocator.cpp
+++ b/cros_gralloc/aidl/Allocator.cpp
@@ -16,7 +16,7 @@
#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
using aidl::android::hardware::common::NativeHandle;
-using BufferDescriptorInfo =
+using BufferDescriptorInfoV4 =
android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
namespace aidl::android::hardware::graphics::allocator::impl {
@@ -78,7 +78,7 @@ ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, i
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
- BufferDescriptorInfo description;
+ BufferDescriptorInfoV4 description;
int ret = ::android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
if (ret) {
@@ -109,7 +109,7 @@ ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, i
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfo& descriptor, int32_t* outStride,
+ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfoV4& descriptor, int32_t* outStride,
native_handle_t** outHandle) {
if (!mDriver) {
ALOGE("Failed to allocate. Driver is uninitialized.\n");
@@ -154,6 +154,85 @@ ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfo& descriptor, i
return ndk::ScopedAStatus::ok();
}
+static BufferDescriptorInfoV4 convertAidlToIMapperV4Descriptor(const BufferDescriptorInfo& info) {
+ return BufferDescriptorInfoV4 {
+ .name{reinterpret_cast<const char*>(info.name.data())},
+ .width = static_cast<uint32_t>(info.width),
+ .height = static_cast<uint32_t>(info.height),
+ .layerCount = static_cast<uint32_t>(info.layerCount),
+ .format = static_cast<::android::hardware::graphics::common::V1_2::PixelFormat>(info.format),
+ .usage = static_cast<uint64_t>(info.usage),
+ .reservedSize = 0,
+ };
+}
+
+ndk::ScopedAStatus Allocator::allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
+ allocator::AllocationResult* outResult) {
+ if (!mDriver) {
+ ALOGE("Failed to allocate. Driver is uninitialized.\n");
+ return ToBinderStatus(AllocationError::NO_RESOURCES);
+ }
+
+ if (!descriptor.additionalOptions.empty()) {
+ return ToBinderStatus(AllocationError::UNSUPPORTED);
+ }
+
+ BufferDescriptorInfoV4 descriptionV4 = convertAidlToIMapperV4Descriptor(descriptor);
+
+ std::vector<native_handle_t*> handles;
+ handles.resize(count, nullptr);
+
+ for (int32_t i = 0; i < count; i++) {
+ ndk::ScopedAStatus status = allocate(descriptionV4, &outResult->stride, &handles[i]);
+ if (!status.isOk()) {
+ for (int32_t j = 0; j < i; j++) {
+ releaseBufferAndHandle(handles[j]);
+ }
+ return status;
+ }
+ }
+
+ outResult->buffers.resize(count);
+ for (int32_t i = 0; i < count; i++) {
+ auto handle = handles[i];
+ outResult->buffers[i] = ::android::dupToAidl(handle);
+ releaseBufferAndHandle(handle);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Allocator::isSupported(const BufferDescriptorInfo& descriptor,
+ bool* outResult) {
+ if (!mDriver) {
+ ALOGE("Failed to allocate. Driver is uninitialized.\n");
+ return ToBinderStatus(AllocationError::NO_RESOURCES);
+ }
+
+ if (!descriptor.additionalOptions.empty()) {
+ *outResult = false;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ struct cros_gralloc_buffer_descriptor crosDescriptor;
+ if (convertToCrosDescriptor(convertAidlToIMapperV4Descriptor(descriptor), &crosDescriptor)) {
+ // Failing to convert the descriptor means the layer count, pixel format, or usage is
+ // unsupported, thus isSupported() = false
+ *outResult = false;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
+
+ *outResult = mDriver->is_supported(&crosDescriptor);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Allocator::getIMapperLibrarySuffix(std::string* outResult) {
+ *outResult = "minigbm";
+ return ndk::ScopedAStatus::ok();
+}
+
::ndk::SpAIBinder Allocator::createBinder() {
auto binder = BnAllocator::createBinder();
AIBinder_setInheritRt(binder.get(), true);
diff --git a/cros_gralloc/aidl/Allocator.h b/cros_gralloc/aidl/Allocator.h
index 801c852..5c12308 100644
--- a/cros_gralloc/aidl/Allocator.h
+++ b/cros_gralloc/aidl/Allocator.h
@@ -26,6 +26,14 @@ class Allocator : public BnAllocator {
ndk::ScopedAStatus allocate(const std::vector<uint8_t>& descriptor, int32_t count,
allocator::AllocationResult* outResult) override;
+ ndk::ScopedAStatus allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
+ allocator::AllocationResult* outResult) override;
+
+ ndk::ScopedAStatus isSupported(const BufferDescriptorInfo& descriptor,
+ bool* outResult) override;
+
+ ndk::ScopedAStatus getIMapperLibrarySuffix(std::string* outResult) override;
+
protected:
ndk::SpAIBinder createBinder() override;
diff --git a/cros_gralloc/aidl/Android.bp b/cros_gralloc/aidl/Android.bp
index 71e2ae7..da8f670 100644
--- a/cros_gralloc/aidl/Android.bp
+++ b/cros_gralloc/aidl/Android.bp
@@ -24,14 +24,14 @@ package {
}
cc_binary {
- name: "android.hardware.graphics.allocator-V1-service.minigbm",
+ name: "android.hardware.graphics.allocator-service.minigbm",
defaults: ["minigbm_cros_gralloc_defaults"],
relative_install_path: "hw",
- init_rc: [":allocator_rc"],
- vintf_fragments: [":allocator_xml"],
+ init_rc: ["allocator.rc"],
+ vintf_fragments: ["allocator.xml"],
vendor: true,
shared_libs: [
- "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.allocator-V2-ndk",
"android.hardware.graphics.mapper@4.0",
"libbase",
"libbinder_ndk",
@@ -49,13 +49,3 @@ cc_binary {
"Main.cpp",
],
}
-
-filegroup {
- name: "allocator_rc",
- srcs: ["allocator.rc"],
-}
-
-filegroup {
- name: "allocator_xml",
- srcs: ["allocator.xml"],
-} \ No newline at end of file
diff --git a/cros_gralloc/aidl/allocator.rc b/cros_gralloc/aidl/allocator.rc
index 5859384..24a7c45 100644
--- a/cros_gralloc/aidl/allocator.rc
+++ b/cros_gralloc/aidl/allocator.rc
@@ -1,4 +1,4 @@
-service vendor.graphics.allocator /vendor/bin/hw/android.hardware.graphics.allocator-V1-service.minigbm
+service vendor.graphics.allocator /vendor/bin/hw/android.hardware.graphics.allocator-service.minigbm
class hal animation
user system
group graphics drmrpc
diff --git a/cros_gralloc/aidl/allocator.xml b/cros_gralloc/aidl/allocator.xml
index 74fd4cd..4d375b3 100644
--- a/cros_gralloc/aidl/allocator.xml
+++ b/cros_gralloc/aidl/allocator.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.graphics.allocator</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IAllocator</name>
<instance>default</instance>
diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc
index e1af7a4..0cac133 100644
--- a/cros_gralloc/cros_gralloc_buffer.cc
+++ b/cros_gralloc/cros_gralloc_buffer.cc
@@ -19,14 +19,14 @@ cros_gralloc_buffer::create(struct bo *acquire_bo,
auto acquire_hnd =
reinterpret_cast<struct cros_gralloc_handle *>(native_handle_clone(borrowed_handle));
if (!acquire_hnd) {
- drv_log("Failed to create cros_gralloc_buffer: failed to clone handle.\n");
+ ALOGE("Failed to create cros_gralloc_buffer: failed to clone handle.");
return {};
}
std::unique_ptr<cros_gralloc_buffer> buffer(
new cros_gralloc_buffer(acquire_bo, acquire_hnd));
if (!buffer) {
- drv_log("Failed to create cros_gralloc_buffer: failed to allocate.\n");
+ ALOGE("Failed to create cros_gralloc_buffer: failed to allocate.");
native_handle_close(acquire_hnd);
native_handle_delete(acquire_hnd);
return {};
@@ -65,6 +65,11 @@ uint32_t cros_gralloc_buffer::get_width() const
return hnd_->width;
}
+uint32_t cros_gralloc_buffer::get_pixel_stride() const
+{
+ return hnd_->pixel_stride;
+}
+
uint32_t cros_gralloc_buffer::get_height() const
{
return hnd_->height;
@@ -138,7 +143,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla
* just use the first kernel buffer.
*/
if (drv_num_buffers_per_bo(bo_) != 1) {
- drv_log("Can only support one buffer per bo.\n");
+ ALOGE("Can only support one buffer per bo.");
return -EINVAL;
}
@@ -162,7 +167,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla
}
if (vaddr == MAP_FAILED) {
- drv_log("Mapping failed.\n");
+ ALOGE("Mapping failed.");
return -EFAULT;
}
}
@@ -177,7 +182,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla
int32_t cros_gralloc_buffer::unlock()
{
if (lockcount_ <= 0) {
- drv_log("Buffer was not locked.\n");
+ ALOGE("Buffer was not locked.");
return -EINVAL;
}
@@ -201,7 +206,7 @@ int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES],
int32_t cros_gralloc_buffer::invalidate()
{
if (lockcount_ <= 0) {
- drv_log("Buffer was not locked.\n");
+ ALOGE("Buffer was not locked.");
return -EINVAL;
}
@@ -214,7 +219,7 @@ int32_t cros_gralloc_buffer::invalidate()
int32_t cros_gralloc_buffer::flush()
{
if (lockcount_ <= 0) {
- drv_log("Buffer was not locked.\n");
+ ALOGE("Buffer was not locked.");
return -EINVAL;
}
@@ -228,7 +233,7 @@ int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) co
{
int32_t reserved_region_fd = hnd_->fds[hnd_->num_planes];
if (reserved_region_fd < 0) {
- drv_log("Buffer does not have reserved region.\n");
+ ALOGE("Buffer does not have reserved region.");
return -EINVAL;
}
@@ -237,7 +242,7 @@ int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) co
mmap(nullptr, hnd_->reserved_region_size, PROT_WRITE | PROT_READ, MAP_SHARED,
reserved_region_fd, 0);
if (reserved_region_addr_ == MAP_FAILED) {
- drv_log("Failed to mmap reserved region: %s.\n", strerror(errno));
+ ALOGE("Failed to mmap reserved region: %s.", strerror(errno));
return -errno;
}
}
diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h
index 21f8306..71947d9 100644
--- a/cros_gralloc/cros_gralloc_buffer.h
+++ b/cros_gralloc/cros_gralloc_buffer.h
@@ -21,6 +21,7 @@ class cros_gralloc_buffer
uint32_t get_id() const;
uint32_t get_width() const;
+ uint32_t get_pixel_stride() const;
uint32_t get_height() const;
uint32_t get_format() const;
uint64_t get_format_modifier() const;
diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc
index 46de30d..a714798 100644
--- a/cros_gralloc/cros_gralloc_driver.cc
+++ b/cros_gralloc/cros_gralloc_driver.cc
@@ -7,6 +7,7 @@
#include "cros_gralloc_driver.h"
#include <cstdlib>
+#include <cutils/properties.h>
#include <fcntl.h>
#include <hardware/gralloc.h>
#include <sys/mman.h>
@@ -25,6 +26,22 @@
// DRM Card nodes start at 0
#define DRM_CARD_NODE_START 0
+class cros_gralloc_driver_preloader
+{
+ public:
+ cros_gralloc_driver_preloader()
+ {
+ drv_preload(true);
+ }
+
+ ~cros_gralloc_driver_preloader()
+ {
+ drv_preload(false);
+ }
+};
+
+static class cros_gralloc_driver_preloader cros_gralloc_driver_preloader;
+
int memfd_create_wrapper(const char *name, unsigned int flags)
{
int fd;
@@ -34,12 +51,12 @@ int memfd_create_wrapper(const char *name, unsigned int flags)
#elif defined(__NR_memfd_create)
fd = syscall(__NR_memfd_create, name, flags);
#else
- drv_log("Failed to create memfd '%s': memfd_create not available.", name);
+ ALOGE("Failed to create memfd '%s': memfd_create not available.", name);
return -1;
#endif
if (fd == -1)
- drv_log("Failed to create memfd '%s': %s.\n", name, strerror(errno));
+ ALOGE("Failed to create memfd '%s': %s.", name, strerror(errno));
return fd;
}
@@ -53,7 +70,7 @@ int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserv
return -errno;
if (ftruncate(reserved_region_fd, reserved_region_size)) {
- drv_log("Failed to set reserved region size: %s.\n", strerror(errno));
+ ALOGE("Failed to set reserved region size: %s.", strerror(errno));
return -errno;
}
@@ -65,7 +82,7 @@ cros_gralloc_driver *cros_gralloc_driver::get_instance()
static cros_gralloc_driver s_instance;
if (!s_instance.is_initialized()) {
- drv_log("Failed to initialize driver.\n");
+ ALOGE("Failed to initialize driver.");
return nullptr;
}
@@ -138,6 +155,9 @@ static void drv_destroy_and_close(struct driver *drv)
cros_gralloc_driver::cros_gralloc_driver() : drv_(init_try_nodes(), drv_destroy_and_close)
{
+ char buf[PROP_VALUE_MAX];
+ property_get("ro.product.device", buf, "unknown");
+ mt8183_camera_quirk_ = !strncmp(buf, "kukui", strlen("kukui"));
}
cros_gralloc_driver::~cros_gralloc_driver()
@@ -159,6 +179,14 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags(
uint64_t resolved_use_flags;
struct combination *combo;
+ if (mt8183_camera_quirk_ && (descriptor->use_flags & BO_USE_CAMERA_READ) &&
+ !(descriptor->use_flags & BO_USE_SCANOUT) &&
+ descriptor->drm_format == DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED) {
+ *out_use_flags = descriptor->use_flags;
+ *out_format = DRM_FORMAT_MTISP_SXYZW10;
+ return true;
+ }
+
drv_resolve_format_and_use_flags(drv_.get(), descriptor->drm_format, descriptor->use_flags,
&resolved_format, &resolved_use_flags);
@@ -172,7 +200,7 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags(
resolved_use_flags &= ~BO_USE_HW_VIDEO_ENCODER;
combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
}
- if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING)) {
+ if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING_MASK)) {
resolved_use_flags &= ~BO_USE_FRONT_RENDERING;
resolved_use_flags |= BO_USE_LINEAR;
combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
@@ -215,7 +243,7 @@ int cros_gralloc_driver::create_reserved_region(const std::string &buffer_name,
if (ret >= 0)
return ret;
- drv_log("Failed to create_reserved_region.\n");
+ ALOGE("Failed to create_reserved_region.");
return -1;
}
@@ -234,14 +262,14 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
std::unique_ptr<cros_gralloc_buffer> buffer;
if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) {
- drv_log("Failed to resolve format and use_flags.\n");
+ ALOGE("Failed to resolve format and use_flags.");
return -EINVAL;
}
bo = drv_bo_create(drv_.get(), descriptor->width, descriptor->height, resolved_format,
resolved_use_flags);
if (!bo) {
- drv_log("Failed to create bo.\n");
+ ALOGE("Failed to create bo.");
return -errno;
}
@@ -251,7 +279,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
* send more than one fd. GL/Vulkan drivers may also have to modified.
*/
if (drv_num_buffers_per_bo(bo) != 1) {
- drv_log("Can only support one buffer per bo.\n");
+ ALOGE("Can only support one buffer per bo.");
goto destroy_bo;
}
@@ -308,7 +336,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
buffer = cros_gralloc_buffer::create(bo, hnd);
if (!buffer) {
- drv_log("Failed to allocate: failed to create cros_gralloc_buffer.\n");
+ ALOGE("Failed to allocate: failed to create cros_gralloc_buffer.");
ret = -1;
goto destroy_hnd;
}
@@ -342,7 +370,7 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
@@ -393,7 +421,7 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
auto scoped_buffer = cros_gralloc_buffer::create(bo, hnd);
if (!scoped_buffer) {
- drv_log("Failed to import: failed to create cros_gralloc_buffer.\n");
+ ALOGE("Failed to import: failed to create cros_gralloc_buffer.");
return -1;
}
buffer = scoped_buffer.get();
@@ -414,13 +442,13 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle)
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (release() called on unregistered handle).\n");
+ ALOGE("Invalid reference (release() called on unregistered handle).");
return -EINVAL;
}
@@ -446,13 +474,13 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (lock() called on unregistered handle).\n");
+ ALOGE("Invalid reference (lock() called on unregistered handle).");
return -EINVAL;
}
@@ -465,13 +493,13 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (unlock() called on unregistered handle).\n");
+ ALOGE("Invalid reference (unlock() called on unregistered handle).");
return -EINVAL;
}
@@ -491,42 +519,35 @@ int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle)
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (invalidate() called on unregistered handle).\n");
+ ALOGE("Invalid reference (invalidate() called on unregistered handle).");
return -EINVAL;
}
return buffer->invalidate();
}
-int32_t cros_gralloc_driver::flush(buffer_handle_t handle, int32_t *release_fence)
+int32_t cros_gralloc_driver::flush(buffer_handle_t handle)
{
std::lock_guard<std::mutex> lock(mutex_);
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (flush() called on unregistered handle).\n");
+ ALOGE("Invalid reference (flush() called on unregistered handle).");
return -EINVAL;
}
- /*
- * From the ANativeWindow::dequeueBuffer documentation:
- *
- * "A value of -1 indicates that the caller may access the buffer immediately without
- * waiting on a fence."
- */
- *release_fence = -1;
return buffer->flush();
}
@@ -536,13 +557,13 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (get_backing_store() called on unregistered handle).\n");
+ ALOGE("Invalid reference (get_backing_store() called on unregistered handle).");
return -EINVAL;
}
@@ -558,13 +579,13 @@ int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t stri
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (resource_info() called on unregistered handle).\n");
+ ALOGE("Invalid reference (resource_info() called on unregistered handle).");
return -EINVAL;
}
@@ -579,14 +600,13 @@ int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle,
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log(
- "Invalid reference (get_reserved_region() called on unregistered handle).\n");
+ ALOGE("Invalid reference (get_reserved_region() called on unregistered handle).");
return -EINVAL;
}
@@ -620,7 +640,7 @@ void cros_gralloc_driver::with_buffer(cros_gralloc_handle_t hnd,
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid reference (with_buffer() called on unregistered handle).\n");
+ ALOGE("Invalid reference (with_buffer() called on unregistered handle).");
return;
}
diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h
index 5678b76..f35757c 100644
--- a/cros_gralloc/cros_gralloc_driver.h
+++ b/cros_gralloc/cros_gralloc_driver.h
@@ -36,7 +36,7 @@ class cros_gralloc_driver
int32_t unlock(buffer_handle_t handle, int32_t *release_fence);
int32_t invalidate(buffer_handle_t handle);
- int32_t flush(buffer_handle_t handle, int32_t *release_fence);
+ int32_t flush(buffer_handle_t handle);
int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store);
int32_t resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES],
@@ -83,6 +83,7 @@ class cros_gralloc_driver
std::mutex mutex_;
std::unordered_map<uint32_t, std::unique_ptr<cros_gralloc_buffer>> buffers_;
std::unordered_map<cros_gralloc_handle_t, cros_gralloc_imported_handle_info> handles_;
+ bool mt8183_camera_quirk_ = false;
};
#endif
diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc
index 3301522..8c86c66 100644
--- a/cros_gralloc/cros_gralloc_helpers.cc
+++ b/cros_gralloc/cros_gralloc_helpers.cc
@@ -12,9 +12,15 @@
/* Define to match AIDL BufferUsage::VIDEO_DECODER. */
#define BUFFER_USAGE_VIDEO_DECODER (1 << 22)
+/* Define to match AIDL BufferUsage::SENSOR_DIRECT_DATA. */
+#define BUFFER_USAGE_SENSOR_DIRECT_DATA (1 << 23)
+
/* Define to match AIDL BufferUsage::GPU_DATA_BUFFER. */
#define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24)
+/* Define to match AIDL PixelFormat::R_8. */
+#define HAL_PIXEL_FORMAT_R8 0x38
+
uint32_t cros_gralloc_convert_format(int format)
{
/*
@@ -50,6 +56,7 @@ uint32_t cros_gralloc_convert_format(int format)
* equal to their size in bytes.
*/
case HAL_PIXEL_FORMAT_BLOB:
+ case HAL_PIXEL_FORMAT_R8:
return DRM_FORMAT_R8;
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED;
@@ -119,11 +126,13 @@ uint64_t cros_gralloc_convert_usage(uint64_t usage)
handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_READ, &use_flags, BO_USE_CAMERA_READ);
handle_usage(&usage, GRALLOC_USAGE_RENDERSCRIPT, &use_flags, BO_USE_RENDERSCRIPT);
handle_usage(&usage, BUFFER_USAGE_VIDEO_DECODER, &use_flags, BO_USE_HW_VIDEO_DECODER);
+ handle_usage(&usage, BUFFER_USAGE_SENSOR_DIRECT_DATA, &use_flags,
+ BO_USE_SENSOR_DIRECT_DATA);
handle_usage(&usage, BUFFER_USAGE_GPU_DATA_BUFFER, &use_flags, BO_USE_GPU_DATA_BUFFER);
- handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING, &use_flags, BO_USE_FRONT_RENDERING);
+ handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING_MASK, &use_flags, BO_USE_FRONT_RENDERING);
if (usage) {
- drv_log("Unhandled gralloc usage: %llx\n", (unsigned long long)usage);
+ ALOGE("Unhandled gralloc usage: %llx", (unsigned long long)usage);
return BO_USE_NONE;
}
@@ -162,10 +171,10 @@ int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence)
*/
int err = sync_wait(fence, 1000);
if (err < 0) {
- drv_log("Timed out on sync wait, err = %s\n", strerror(errno));
+ ALOGE("Timed out on sync wait, err = %s", strerror(errno));
err = sync_wait(fence, -1);
if (err < 0) {
- drv_log("sync wait error = %s\n", strerror(errno));
+ ALOGE("sync wait error = %s", strerror(errno));
return -errno;
}
}
@@ -173,7 +182,7 @@ int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence)
if (close_fence) {
err = close(fence);
if (err) {
- drv_log("Unable to close fence fd, err = %s\n", strerror(errno));
+ ALOGE("Unable to close fence fd, err = %s", strerror(errno));
return -errno;
}
}
diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h
index 312d2f7..9fcb995 100644
--- a/cros_gralloc/cros_gralloc_helpers.h
+++ b/cros_gralloc/cros_gralloc_helpers.h
@@ -10,6 +10,7 @@
#include "../drv.h"
#include "cros_gralloc_handle.h"
+#include <log/log.h>
#include <system/graphics.h>
#include <system/window.h>
@@ -20,6 +21,9 @@
// BO_USE_FRONT_RENDERING or BO_USE_LINEAR upon buffer allocaton.
#define BUFFER_USAGE_FRONT_RENDERING (1U << 28)
+// Adopt BufferUsage::FRONT_BUFFER from api level 33
+#define BUFFER_USAGE_FRONT_RENDERING_MASK (BUFFER_USAGE_FRONT_RENDERING | (1ULL << 32))
+
struct cros_gralloc_buffer_descriptor {
uint32_t width;
uint32_t height;
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index ce62521..3412e85 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -84,10 +84,10 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa
descriptor.reserved_region_size = 0;
if (!mod->driver->is_supported(&descriptor)) {
- drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, "
- "drv_format: %4.4s, use_flags: %llu\n",
- format, usage, reinterpret_cast<char *>(&descriptor.drm_format),
- static_cast<unsigned long long>(descriptor.use_flags));
+ ALOGE("Unsupported combination -- HAL format: %u, HAL usage: %u, "
+ "drv_format: %4.4s, use_flags: %llu",
+ format, usage, reinterpret_cast<char *>(&descriptor.drm_format),
+ static_cast<unsigned long long>(descriptor.use_flags));
return -EINVAL;
}
@@ -160,7 +160,7 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct
}
if (strcmp(name, GRALLOC_HARDWARE_GPU0)) {
- drv_log("Incorrect device name - %s.\n", name);
+ ALOGE("Incorrect device name - %s.", name);
return -EINVAL;
}
@@ -247,7 +247,7 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
va_end(args);
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
break;
@@ -351,12 +351,12 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.\n");
+ ALOGE("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.");
return -EINVAL;
}
@@ -402,13 +402,13 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
- drv_log("Invalid handle.\n");
+ ALOGE("Invalid handle.");
return -EINVAL;
}
if (!gralloc0_droid_yuv_format(hnd->droid_format) &&
hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
- drv_log("Non-YUV format not compatible.\n");
+ ALOGE("Non-YUV format not compatible.");
return -EINVAL;
}
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
index 43c0b0c..3166793 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
@@ -35,12 +35,12 @@ Error CrosGralloc4Allocator::initializeMetadata(
cros_gralloc_handle_t crosHandle,
const struct cros_gralloc_buffer_descriptor& crosDescriptor) {
if (!mDriver) {
- drv_log("Failed to initializeMetadata. Driver is uninitialized.\n");
+ ALOGE("Failed to initializeMetadata. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
if (!crosHandle) {
- drv_log("Failed to initializeMetadata. Invalid handle.\n");
+ ALOGE("Failed to initializeMetadata. Invalid handle.");
return Error::BAD_BUFFER;
}
@@ -48,7 +48,7 @@ Error CrosGralloc4Allocator::initializeMetadata(
uint64_t size;
int ret = mDriver->get_reserved_region(crosHandle, &addr, &size);
if (ret) {
- drv_log("Failed to getReservedRegion.\n");
+ ALOGE("Failed to getReservedRegion.");
return Error::NO_RESOURCES;
}
@@ -65,7 +65,7 @@ Error CrosGralloc4Allocator::initializeMetadata(
Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
hidl_handle* outHandle) {
if (!mDriver) {
- drv_log("Failed to allocate. Driver is uninitialized.\n");
+ ALOGE("Failed to allocate. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
@@ -84,8 +84,8 @@ Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, ui
std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format);
std::string pixelFormatString = getPixelFormatString(descriptor.format);
std::string usageString = getUsageString(descriptor.usage);
- drv_log("Unsupported combination -- pixel format: %s, drm format:%s, usage: %s\n",
- pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
+ ALOGE("Unsupported combination -- pixel format: %s, drm format:%s, usage: %s",
+ pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
return Error::UNSUPPORTED;
}
@@ -116,7 +116,7 @@ Return<void> CrosGralloc4Allocator::allocate(const hidl_vec<uint8_t>& descriptor
hidl_vec<hidl_handle> handles;
if (!mDriver) {
- drv_log("Failed to allocate. Driver is uninitialized.\n");
+ ALOGE("Failed to allocate. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, 0, handles);
return Void();
}
@@ -125,7 +125,7 @@ Return<void> CrosGralloc4Allocator::allocate(const hidl_vec<uint8_t>& descriptor
int ret = android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
if (ret) {
- drv_log("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
+ ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.", ret);
hidlCb(Error::BAD_DESCRIPTOR, 0, handles);
return Void();
}
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
index cc2c4d5..a8a4f52 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
@@ -34,26 +34,26 @@ Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& de
hidl_vec<uint8_t> descriptor;
if (description.width == 0) {
- drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width);
+ ALOGE("Failed to createDescriptor. Bad width: %d.", description.width);
hidlCb(Error::BAD_VALUE, descriptor);
return Void();
}
if (description.height == 0) {
- drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height);
+ ALOGE("Failed to createDescriptor. Bad height: %d.", description.height);
hidlCb(Error::BAD_VALUE, descriptor);
return Void();
}
if (description.layerCount == 0) {
- drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount);
+ ALOGE("Failed to createDescriptor. Bad layer count: %d.", description.layerCount);
hidlCb(Error::BAD_VALUE, descriptor);
return Void();
}
int ret = android::gralloc4::encodeBufferDescriptorInfo(description, &descriptor);
if (ret) {
- drv_log("Failed to createDescriptor. Failed to encode: %d.\n", ret);
+ ALOGE("Failed to createDescriptor. Failed to encode: %d.", ret);
hidlCb(Error::BAD_VALUE, descriptor);
return Void();
}
@@ -64,21 +64,21 @@ Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& de
Return<void> CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to import buffer. Driver is uninitialized.\n");
+ ALOGE("Failed to import buffer. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, nullptr);
return Void();
}
const native_handle_t* bufferHandle = handle.getNativeHandle();
if (!bufferHandle || bufferHandle->numFds == 0) {
- drv_log("Failed to importBuffer. Bad handle.\n");
+ ALOGE("Failed to importBuffer. Bad handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
if (!importedBufferHandle) {
- drv_log("Failed to importBuffer. Handle clone failed: %s.\n", strerror(errno));
+ ALOGE("Failed to importBuffer. Handle clone failed: %s.", strerror(errno));
hidlCb(Error::NO_RESOURCES, nullptr);
return Void();
}
@@ -97,13 +97,13 @@ Return<void> CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importB
Return<Error> CrosGralloc4Mapper::freeBuffer(void* rawHandle) {
if (!mDriver) {
- drv_log("Failed to freeBuffer. Driver is uninitialized.\n");
+ ALOGE("Failed to freeBuffer. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to freeBuffer. Empty handle.\n");
+ ALOGE("Failed to freeBuffer. Empty handle.");
return Error::BAD_BUFFER;
}
@@ -121,43 +121,49 @@ Return<Error> CrosGralloc4Mapper::validateBufferSize(void* rawHandle,
const BufferDescriptorInfo& descriptor,
uint32_t stride) {
if (!mDriver) {
- drv_log("Failed to validateBufferSize. Driver is uninitialized.\n");
+ ALOGE("Failed to validateBufferSize. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to validateBufferSize. Empty handle.\n");
+ ALOGE("Failed to validateBufferSize. Empty handle.");
return Error::BAD_BUFFER;
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
- drv_log("Failed to validateBufferSize. Invalid handle.\n");
+ ALOGE("Failed to validateBufferSize. Invalid handle.");
return Error::BAD_BUFFER;
}
PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
if (descriptor.format != crosHandleFormat) {
- drv_log("Failed to validateBufferSize. Format mismatch.\n");
+ ALOGE("Failed to validateBufferSize. Format mismatch.");
return Error::BAD_BUFFER;
}
if (descriptor.width != crosHandle->width) {
- drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width,
- crosHandle->width);
+ ALOGE("Failed to validateBufferSize. Width mismatch (%d vs %d).", descriptor.width,
+ crosHandle->width);
return Error::BAD_VALUE;
}
if (descriptor.height != crosHandle->height) {
- drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height,
- crosHandle->height);
+ ALOGE("Failed to validateBufferSize. Height mismatch (%d vs %d).", descriptor.height,
+ crosHandle->height);
return Error::BAD_VALUE;
}
- if (stride != crosHandle->pixel_stride) {
- drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride,
- crosHandle->pixel_stride);
+ if (crosHandle->droid_format == HAL_PIXEL_FORMAT_BLOB) {
+ if (stride > crosHandle->pixel_stride) {
+ ALOGE("Failed to validateBufferSize. Oversized stride (%d vs %d).", stride,
+ crosHandle->pixel_stride);
+ return Error::BAD_VALUE;
+ }
+ } else if (stride != crosHandle->pixel_stride) {
+ ALOGE("Failed to validateBufferSize. Stride mismatch (%d vs %d).", stride,
+ crosHandle->pixel_stride);
return Error::BAD_VALUE;
}
@@ -166,14 +172,14 @@ Return<Error> CrosGralloc4Mapper::validateBufferSize(void* rawHandle,
Return<void> CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to getTransportSize. Driver is uninitialized.\n");
+ ALOGE("Failed to getTransportSize. Driver is uninitialized.");
hidlCb(Error::BAD_BUFFER, 0, 0);
return Void();
}
native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to getTransportSize. Bad handle.\n");
+ ALOGE("Failed to getTransportSize. Bad handle.");
hidlCb(Error::BAD_BUFFER, 0, 0);
return Void();
}
@@ -186,20 +192,20 @@ Return<void> CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportS
Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const Rect& region,
const hidl_handle& acquireFence, lock_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to lock. Driver is uninitialized.\n");
+ ALOGE("Failed to lock. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, nullptr);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawBuffer);
if (!bufferHandle) {
- drv_log("Failed to lock. Empty handle.\n");
+ ALOGE("Failed to lock. Empty handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
if (cpuUsage == 0) {
- drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage);
+ ALOGE("Failed to lock. Bad cpu usage: %" PRIu64 ".", cpuUsage);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
@@ -207,52 +213,52 @@ Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const
uint32_t mapUsage = 0;
int ret = convertToMapUsage(cpuUsage, &mapUsage);
if (ret) {
- drv_log("Failed to lock. Convert usage failed.\n");
+ ALOGE("Failed to lock. Convert usage failed.");
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (crosHandle == nullptr) {
- drv_log("Failed to lock. Invalid handle.\n");
+ ALOGE("Failed to lock. Invalid handle.");
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.left < 0) {
- drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left);
+ ALOGE("Failed to lock. Invalid region: negative left value %d.", region.left);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.top < 0) {
- drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top);
+ ALOGE("Failed to lock. Invalid region: negative top value %d.", region.top);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.width < 0) {
- drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width);
+ ALOGE("Failed to lock. Invalid region: negative width value %d.", region.width);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.height < 0) {
- drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height);
+ ALOGE("Failed to lock. Invalid region: negative height value %d.", region.height);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.width > crosHandle->width) {
- drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n",
- region.width, crosHandle->width);
+ ALOGE("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).",
+ region.width, crosHandle->width);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
if (region.height > crosHandle->height) {
- drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n",
- region.height, crosHandle->height);
+ ALOGE("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).",
+ region.height, crosHandle->height);
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
@@ -270,7 +276,7 @@ Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const
int acquireFenceFd = -1;
ret = convertToFenceFd(acquireFence, &acquireFenceFd);
if (ret) {
- drv_log("Failed to lock. Bad acquire fence.\n");
+ ALOGE("Failed to lock. Bad acquire fence.");
hidlCb(Error::BAD_VALUE, nullptr);
return Void();
}
@@ -289,14 +295,14 @@ Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const
Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to unlock. Driver is uninitialized.\n");
+ ALOGE("Failed to unlock. Driver is uninitialized.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to unlock. Empty handle.\n");
+ ALOGE("Failed to unlock. Empty handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
@@ -304,7 +310,7 @@ Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
int releaseFenceFd = -1;
int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
if (ret) {
- drv_log("Failed to unlock.\n");
+ ALOGE("Failed to unlock.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
@@ -312,7 +318,7 @@ Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
hidl_handle releaseFenceHandle;
ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
if (ret) {
- drv_log("Failed to unlock. Failed to convert release fence to handle.\n");
+ ALOGE("Failed to unlock. Failed to convert release fence to handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
@@ -323,22 +329,28 @@ Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedBuffer_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to flushLockedBuffer. Driver is uninitialized.\n");
+ ALOGE("Failed to flushLockedBuffer. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, nullptr);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to flushLockedBuffer. Empty handle.\n");
+ ALOGE("Failed to flushLockedBuffer. Empty handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
+ /*
+ * From the ANativeWindow::dequeueBuffer documentation:
+ *
+ * "A value of -1 indicates that the caller may access the buffer immediately without
+ * waiting on a fence."
+ */
int releaseFenceFd = -1;
- int ret = mDriver->flush(bufferHandle, &releaseFenceFd);
+ int ret = mDriver->flush(bufferHandle);
if (ret) {
- drv_log("Failed to flushLockedBuffer. Flush failed.\n");
+ ALOGE("Failed to flushLockedBuffer. Flush failed.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
@@ -346,7 +358,7 @@ Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedB
hidl_handle releaseFenceHandle;
ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
if (ret) {
- drv_log("Failed to flushLockedBuffer. Failed to convert release fence to handle.\n");
+ ALOGE("Failed to flushLockedBuffer. Failed to convert release fence to handle.");
hidlCb(Error::BAD_BUFFER, nullptr);
return Void();
}
@@ -357,19 +369,19 @@ Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedB
Return<Error> CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) {
if (!mDriver) {
- drv_log("Failed to rereadLockedBuffer. Driver is uninitialized.\n");
+ ALOGE("Failed to rereadLockedBuffer. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to rereadLockedBuffer. Empty handle.\n");
+ ALOGE("Failed to rereadLockedBuffer. Empty handle.");
return Error::BAD_BUFFER;
}
int ret = mDriver->invalidate(bufferHandle);
if (ret) {
- drv_log("Failed to rereadLockedBuffer. Failed to invalidate.\n");
+ ALOGE("Failed to rereadLockedBuffer. Failed to invalidate.");
return Error::BAD_BUFFER;
}
@@ -379,7 +391,7 @@ Return<Error> CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) {
Return<void> CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descriptor,
isSupported_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to isSupported. Driver is uninitialized.\n");
+ ALOGE("Failed to isSupported. Driver is uninitialized.");
hidlCb(Error::BAD_VALUE, false);
return Void();
}
@@ -399,21 +411,21 @@ Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metada
hidl_vec<uint8_t> encodedMetadata;
if (!mDriver) {
- drv_log("Failed to get. Driver is uninitialized.\n");
+ ALOGE("Failed to get. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, encodedMetadata);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to get. Empty handle.\n");
+ ALOGE("Failed to get. Empty handle.");
hidlCb(Error::BAD_BUFFER, encodedMetadata);
return Void();
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
- drv_log("Failed to get. Invalid handle.\n");
+ ALOGE("Failed to get. Invalid handle.");
hidlCb(Error::BAD_BUFFER, encodedMetadata);
return Void();
}
@@ -429,13 +441,13 @@ Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
hidl_vec<uint8_t> encodedMetadata;
if (!mDriver) {
- drv_log("Failed to get. Driver is uninitialized.\n");
+ ALOGE("Failed to get. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, encodedMetadata);
return Void();
}
if (!crosBuffer) {
- drv_log("Failed to get. Invalid buffer.\n");
+ ALOGE("Failed to get. Invalid buffer.");
hidlCb(Error::BAD_BUFFER, encodedMetadata);
return Void();
}
@@ -448,7 +460,7 @@ Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
metadataType == android::gralloc4::MetadataType_Smpte2086) {
Error error = getMetadata(crosBuffer, &crosMetadata);
if (error != Error::NONE) {
- drv_log("Failed to get. Failed to get buffer metadata.\n");
+ ALOGE("Failed to get. Failed to get buffer metadata.");
hidlCb(Error::NO_RESOURCES, encodedMetadata);
return Void();
}
@@ -540,7 +552,7 @@ Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
if (status != android::NO_ERROR) {
hidlCb(Error::NO_RESOURCES, encodedMetadata);
- drv_log("Failed to get. Failed to encode metadata.\n");
+ ALOGE("Failed to get. Failed to encode metadata.");
return Void();
}
@@ -551,19 +563,19 @@ Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType,
const hidl_vec<uint8_t>& encodedMetadata) {
if (!mDriver) {
- drv_log("Failed to set. Driver is uninitialized.\n");
+ ALOGE("Failed to set. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to set. Empty handle.\n");
+ ALOGE("Failed to set. Empty handle.");
return Error::BAD_BUFFER;
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
- drv_log("Failed to set. Invalid handle.\n");
+ ALOGE("Failed to set. Invalid handle.");
return Error::BAD_BUFFER;
}
@@ -601,12 +613,12 @@ Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metad
Error CrosGralloc4Mapper::set(cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType,
const android::hardware::hidl_vec<uint8_t>& encodedMetadata) {
if (!mDriver) {
- drv_log("Failed to set. Driver is uninitialized.\n");
+ ALOGE("Failed to set. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
if (!crosBuffer) {
- drv_log("Failed to set. Invalid buffer.\n");
+ ALOGE("Failed to set. Invalid buffer.");
return Error::BAD_BUFFER;
}
@@ -614,32 +626,32 @@ Error CrosGralloc4Mapper::set(cros_gralloc_buffer* crosBuffer, const MetadataTyp
Error error = getMutableMetadata(crosBuffer, &crosMetadata);
if (error != Error::NONE) {
- drv_log("Failed to set. Failed to get buffer metadata.\n");
+ ALOGE("Failed to set. Failed to get buffer metadata.");
return Error::UNSUPPORTED;
}
if (metadataType == android::gralloc4::MetadataType_BlendMode) {
auto status = android::gralloc4::decodeBlendMode(encodedMetadata, &crosMetadata->blendMode);
if (status != android::NO_ERROR) {
- drv_log("Failed to set. Failed to decode blend mode.\n");
+ ALOGE("Failed to set. Failed to decode blend mode.");
return Error::UNSUPPORTED;
}
} else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
auto status = android::gralloc4::decodeCta861_3(encodedMetadata, &crosMetadata->cta861_3);
if (status != android::NO_ERROR) {
- drv_log("Failed to set. Failed to decode cta861_3.\n");
+ ALOGE("Failed to set. Failed to decode cta861_3.");
return Error::UNSUPPORTED;
}
} else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
auto status = android::gralloc4::decodeDataspace(encodedMetadata, &crosMetadata->dataspace);
if (status != android::NO_ERROR) {
- drv_log("Failed to set. Failed to decode dataspace.\n");
+ ALOGE("Failed to set. Failed to decode dataspace.");
return Error::UNSUPPORTED;
}
} else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
auto status = android::gralloc4::decodeSmpte2086(encodedMetadata, &crosMetadata->smpte2086);
if (status != android::NO_ERROR) {
- drv_log("Failed to set. Failed to decode smpte2086.\n");
+ ALOGE("Failed to set. Failed to decode smpte2086.");
return Error::UNSUPPORTED;
}
}
@@ -652,24 +664,23 @@ int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t b
uint32_t drmFormat;
if (convertToDrmFormat(pixelFormat, &drmFormat)) {
std::string pixelFormatString = getPixelFormatString(pixelFormat);
- drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n",
- pixelFormatString.c_str());
+ ALOGE("Failed to getResolvedDrmFormat. Failed to convert format %s",
+ pixelFormatString.c_str());
return -EINVAL;
}
uint64_t usage;
if (convertToBufferUsage(bufferUsage, &usage)) {
std::string usageString = getUsageString(bufferUsage);
- drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n",
- usageString.c_str());
+ ALOGE("Failed to getResolvedDrmFormat. Failed to convert usage %s", usageString.c_str());
return -EINVAL;
}
uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
std::string drmFormatString = get_drm_format_string(drmFormat);
- drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n",
- drmFormatString.c_str());
+ ALOGE("Failed to getResolvedDrmFormat. Failed to resolve drm format %s",
+ drmFormatString.c_str());
return -EINVAL;
}
@@ -684,7 +695,7 @@ Return<void> CrosGralloc4Mapper::getFromBufferDescriptorInfo(
hidl_vec<uint8_t> encodedMetadata;
if (!mDriver) {
- drv_log("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.\n");
+ ALOGE("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, encodedMetadata);
return Void();
}
@@ -769,7 +780,7 @@ Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadat
hidl_vec<MetadataTypeDescription> supported;
if (!mDriver) {
- drv_log("Failed to listSupportedMetadataTypes. Driver is uninitialized.\n");
+ ALOGE("Failed to listSupportedMetadataTypes. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, supported);
return Void();
}
@@ -866,6 +877,12 @@ Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadat
/*isSettable=*/false,
},
{
+ android::gralloc4::MetadataType_Crop,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
android::gralloc4::MetadataType_Dataspace,
"",
/*isGettable=*/true,
@@ -905,21 +922,21 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlC
BufferDump bufferDump;
if (!mDriver) {
- drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
+ ALOGE("Failed to dumpBuffer. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, bufferDump);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to dumpBuffer. Empty handle.\n");
+ ALOGE("Failed to dumpBuffer. Empty handle.");
hidlCb(Error::BAD_BUFFER, bufferDump);
return Void();
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
- drv_log("Failed to dumpBuffer. Invalid handle.\n");
+ ALOGE("Failed to dumpBuffer. Invalid handle.");
hidlCb(Error::BAD_BUFFER, bufferDump);
return Void();
}
@@ -935,7 +952,7 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(const cros_gralloc_buffer* crosBuffe
BufferDump bufferDump;
if (!mDriver) {
- drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
+ ALOGE("Failed to dumpBuffer. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, bufferDump);
return Void();
}
@@ -1010,7 +1027,7 @@ Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) {
std::vector<BufferDump> bufferDumps;
if (!mDriver) {
- drv_log("Failed to dumpBuffers. Driver is uninitialized.\n");
+ ALOGE("Failed to dumpBuffers. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, bufferDumps);
return Void();
}
@@ -1035,18 +1052,18 @@ Error CrosGralloc4Mapper::getReservedRegionArea(const cros_gralloc_buffer* crosB
ReservedRegionArea area, void** outAddr,
uint64_t* outSize) {
if (!mDriver) {
- drv_log("Failed to getReservedRegionArea. Driver is uninitialized.\n");
+ ALOGE("Failed to getReservedRegionArea. Driver is uninitialized.");
return Error::NO_RESOURCES;
}
if (!crosBuffer) {
- drv_log("Failed to getReservedRegionArea. Invalid buffer.\n");
+ ALOGE("Failed to getReservedRegionArea. Invalid buffer.");
return Error::BAD_BUFFER;
}
int ret = crosBuffer->get_reserved_region(outAddr, outSize);
if (ret) {
- drv_log("Failed to getReservedRegionArea.\n");
+ ALOGE("Failed to getReservedRegionArea.");
*outAddr = nullptr;
*outSize = 0;
return Error::NO_RESOURCES;
@@ -1102,21 +1119,21 @@ Error CrosGralloc4Mapper::getMutableMetadata(cros_gralloc_buffer* crosBuffer,
Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) {
if (!mDriver) {
- drv_log("Failed to getReservedRegion. Driver is uninitialized.\n");
+ ALOGE("Failed to getReservedRegion. Driver is uninitialized.");
hidlCb(Error::NO_RESOURCES, nullptr, 0);
return Void();
}
buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
if (!bufferHandle) {
- drv_log("Failed to getReservedRegion. Empty handle.\n");
+ ALOGE("Failed to getReservedRegion. Empty handle.");
hidlCb(Error::BAD_BUFFER, nullptr, 0);
return Void();
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
- drv_log("Failed to getReservedRegion. Invalid handle.\n");
+ ALOGE("Failed to getReservedRegion. Invalid handle.");
hidlCb(Error::BAD_BUFFER, nullptr, 0);
return Void();
}
@@ -1131,7 +1148,7 @@ Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedR
});
if (error != Error::NONE) {
- drv_log("Failed to getReservedRegion. Failed to getReservedRegionArea.\n");
+ ALOGE("Failed to getReservedRegion. Failed to getReservedRegionArea.");
hidlCb(Error::BAD_BUFFER, nullptr, 0);
return Void();
}
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
index 6c07189..515269a 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
@@ -64,18 +64,17 @@ int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor,
outCrosDescriptor->droid_usage = descriptor.usage;
outCrosDescriptor->reserved_region_size = descriptor.reservedSize;
if (descriptor.layerCount > 1) {
- drv_log("Failed to convert descriptor. Unsupported layerCount: %d\n",
- descriptor.layerCount);
+ ALOGE("Failed to convert descriptor. Unsupported layerCount: %d", descriptor.layerCount);
return -EINVAL;
}
if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
std::string pixelFormatString = getPixelFormatString(descriptor.format);
- drv_log("Failed to convert descriptor. Unsupported format %s\n", pixelFormatString.c_str());
+ ALOGE("Failed to convert descriptor. Unsupported format %s", pixelFormatString.c_str());
return -EINVAL;
}
if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
std::string usageString = getUsageString(descriptor.usage);
- drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str());
+ ALOGE("Failed to convert descriptor. Unsupported usage flags %s", usageString.c_str());
return -EINVAL;
}
return 0;
@@ -342,7 +341,7 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap
},
{
.components = {{.type = android::gralloc4::
- PlaneLayoutComponentType_CB,
+ PlaneLayoutComponentType_CR,
.offsetInBits = 0,
.sizeInBits = 8}},
.sampleIncrementInBits = 8,
@@ -351,7 +350,7 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap
},
{
.components = {{.type = android::gralloc4::
- PlaneLayoutComponentType_CR,
+ PlaneLayoutComponentType_CB,
.offsetInBits = 0,
.sizeInBits = 8}},
.sampleIncrementInBits = 8,
@@ -398,7 +397,7 @@ int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayout
const auto& planeLayoutsMap = GetPlaneLayoutsMap();
const auto it = planeLayoutsMap.find(drmFormat);
if (it == planeLayoutsMap.end()) {
- drv_log("Unknown plane layout for format %d\n", drmFormat);
+ ALOGE("Unknown plane layout for format %d", drmFormat);
return -EINVAL;
}
diff --git a/cros_gralloc/mapper_stablec/.clang-format b/cros_gralloc/mapper_stablec/.clang-format
new file mode 100644
index 0000000..e5e7076
--- /dev/null
+++ b/cros_gralloc/mapper_stablec/.clang-format
@@ -0,0 +1,19 @@
+# Copyright 2022 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.
+#
+# This directory is formatted to match the format of the interfaces implemented.
+
+BasedOnStyle: Google
+Standard: Cpp11
+AccessModifierOffset: -2
+AllowShortFunctionsOnASingleLine: Inline
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IncludeBlocks: Preserve
+IndentWidth: 4
+ContinuationIndentWidth: 8
+PointerAlignment: Left
+TabWidth: 4
+UseTab: Never \ No newline at end of file
diff --git a/cros_gralloc/mapper_stablec/Android.bp b/cros_gralloc/mapper_stablec/Android.bp
new file mode 100644
index 0000000..b25be17
--- /dev/null
+++ b/cros_gralloc/mapper_stablec/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_minigbm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["external_minigbm_license"],
+}
+
+cc_library_shared {
+ name: "mapper.minigbm",
+ defaults: ["minigbm_gralloc4_common_defaults"],
+ vintf_fragments: ["mapper.minigbm.xml"],
+ shared_libs: [
+ "android.hardware.graphics.allocator-V2-ndk",
+ "libminigbm_gralloc",
+ ],
+ header_libs: [
+ "libbase_headers",
+ "libimapper_stablec",
+ "libimapper_providerutils",
+ ],
+ srcs: [
+ ":minigbm_gralloc4_mapper_files",
+ "Mapper.cpp",
+ ],
+ cpp_std: "c++20",
+}
diff --git a/cros_gralloc/mapper_stablec/Mapper.cpp b/cros_gralloc/mapper_stablec/Mapper.cpp
new file mode 100644
index 0000000..6c4ac86
--- /dev/null
+++ b/cros_gralloc/mapper_stablec/Mapper.cpp
@@ -0,0 +1,745 @@
+/*
+ * Copyright 2022 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 <aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+#include <cutils/native_handle.h>
+#include <gralloctypes/Gralloc4.h>
+
+#include "cros_gralloc/cros_gralloc_driver.h"
+#include "cros_gralloc/cros_gralloc_handle.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
+
+using namespace ::aidl::android::hardware::graphics::common;
+using namespace ::android::hardware::graphics::mapper;
+using ::aidl::android::hardware::graphics::allocator::BufferDescriptorInfo;
+using ::android::base::unique_fd;
+
+#define REQUIRE_DRIVER() \
+ if (!mDriver) { \
+ ALOGE("Failed to %s. Driver is uninitialized.", __func__); \
+ return AIMAPPER_ERROR_NO_RESOURCES; \
+ }
+
+#define VALIDATE_BUFFER_HANDLE(bufferHandle) \
+ if (!(bufferHandle)) { \
+ ALOGE("Failed to %s. Null buffer_handle_t.", __func__); \
+ return AIMAPPER_ERROR_BAD_BUFFER; \
+ }
+
+#define VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle) \
+ REQUIRE_DRIVER() \
+ VALIDATE_BUFFER_HANDLE(bufferHandle)
+
+static_assert(CROS_GRALLOC4_METADATA_MAX_NAME_SIZE >=
+ decltype(std::declval<BufferDescriptorInfo>().name){}.size(),
+ "Metadata name storage too small to fit a BufferDescriptorInfo::name");
+
+constexpr const char* STANDARD_METADATA_NAME =
+ "android.hardware.graphics.common.StandardMetadataType";
+
+static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
+ return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
+}
+
+class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl {
+ private:
+ cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance();
+
+ public:
+ explicit CrosGrallocMapperV5() = default;
+ ~CrosGrallocMapperV5() override = default;
+
+ AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle) override;
+
+ AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) override;
+
+ AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer, uint32_t* _Nonnull outNumFds,
+ uint32_t* _Nonnull outNumInts) override;
+
+ AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage, ARect accessRegion,
+ int acquireFence, void* _Nullable* _Nonnull outData) override;
+
+ AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) override;
+
+ AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) override;
+
+ AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) override;
+
+ int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
+ void* _Nonnull outData, size_t outDataSize) override;
+
+ int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer, int64_t standardMetadataType,
+ void* _Nonnull outData, size_t outDataSize) override;
+
+ AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
+ const void* _Nonnull metadata, size_t metadataSize) override;
+
+ AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType, const void* _Nonnull metadata,
+ size_t metadataSize) override;
+
+ AIMapper_Error listSupportedMetadataTypes(
+ const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+ size_t* _Nonnull outNumberOfDescriptions) override;
+
+ AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) override;
+
+ AIMapper_Error dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) override;
+
+ AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
+ void* _Nullable* _Nonnull outReservedRegion,
+ uint64_t* _Nonnull outReservedSize) override;
+
+ private:
+ enum class ReservedRegionArea {
+ /* CrosGralloc4Metadata */
+ MAPPER4_METADATA,
+
+ /* External user metadata */
+ USER_METADATA,
+ };
+
+ AIMapper_Error getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
+ ReservedRegionArea area, void** outAddr,
+ uint64_t* outSize);
+
+ AIMapper_Error getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
+ const CrosGralloc4Metadata** outMetadata);
+
+ AIMapper_Error getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
+ CrosGralloc4Metadata** outMetadata);
+
+ template <typename F, StandardMetadataType TYPE>
+ int32_t getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
+ StandardMetadata<TYPE>);
+
+ template <StandardMetadataType TYPE>
+ AIMapper_Error setStandardMetadata(CrosGralloc4Metadata* crosMetadata,
+ typename StandardMetadata<TYPE>::value_type&& value);
+
+ void dumpBuffer(
+ const cros_gralloc_buffer* crosBuffer,
+ std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback);
+};
+
+AIMapper_Error CrosGrallocMapperV5::importBuffer(
+ const native_handle_t* _Nonnull bufferHandle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle) {
+ REQUIRE_DRIVER()
+
+ if (!bufferHandle || bufferHandle->numFds == 0) {
+ ALOGE("Failed to importBuffer. Bad handle.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
+ if (!importedBufferHandle) {
+ ALOGE("Failed to importBuffer. Handle clone failed: %s.", strerror(errno));
+ return AIMAPPER_ERROR_NO_RESOURCES;
+ }
+
+ int ret = mDriver->retain(importedBufferHandle);
+ if (ret) {
+ native_handle_close(importedBufferHandle);
+ native_handle_delete(importedBufferHandle);
+ return AIMAPPER_ERROR_NO_RESOURCES;
+ }
+
+ *outBufferHandle = importedBufferHandle;
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::freeBuffer(buffer_handle_t _Nonnull buffer) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
+
+ int ret = mDriver->release(buffer);
+ if (ret) {
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ native_handle_close(buffer);
+ native_handle_delete(const_cast<native_handle_t*>(buffer));
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::getTransportSize(buffer_handle_t _Nonnull bufferHandle,
+ uint32_t* _Nonnull outNumFds,
+ uint32_t* _Nonnull outNumInts) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
+
+ // No local process data is currently stored on the native handle.
+ *outNumFds = bufferHandle->numFds;
+ *outNumInts = bufferHandle->numInts;
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::lock(buffer_handle_t _Nonnull bufferHandle, uint64_t cpuUsage,
+ ARect region, int acquireFenceRawFd,
+ void* _Nullable* _Nonnull outData) {
+ // We take ownership of the FD in all cases, even for errors
+ unique_fd acquireFence(acquireFenceRawFd);
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
+ if (cpuUsage == 0) {
+ ALOGE("Failed to lock. Bad cpu usage: %" PRIu64 ".", cpuUsage);
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ uint32_t mapUsage = cros_gralloc_convert_map_usage(cpuUsage);
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (crosHandle == nullptr) {
+ ALOGE("Failed to lock. Invalid handle.");
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ struct rectangle rect;
+
+ // An access region of all zeros means the entire buffer.
+ if (region.left == 0 && region.top == 0 && region.right == 0 && region.bottom == 0) {
+ rect = {0, 0, crosHandle->width, crosHandle->height};
+ } else {
+ if (region.left < 0 || region.top < 0 || region.right <= region.left ||
+ region.bottom <= region.top) {
+ ALOGE("Failed to lock. Invalid accessRegion: [%d, %d, %d, %d]", region.left, region.top,
+ region.right, region.bottom);
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ if (region.right > crosHandle->width) {
+ ALOGE("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).",
+ region.right, crosHandle->width);
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ if (region.bottom > crosHandle->height) {
+ ALOGE("Failed to lock. Invalid region: height greater than buffer height (%d vs "
+ "%d).",
+ region.bottom, crosHandle->height);
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
+ static_cast<uint32_t>(region.right - region.left),
+ static_cast<uint32_t>(region.bottom - region.top)};
+ }
+
+ uint8_t* addr[DRV_MAX_PLANES];
+ int32_t status = mDriver->lock(bufferHandle, acquireFence.get(),
+ /*close_acquire_fence=*/false, &rect, mapUsage, addr);
+ if (status) {
+ return AIMAPPER_ERROR_BAD_VALUE;
+ }
+
+ *outData = addr[0];
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::unlock(buffer_handle_t _Nonnull buffer,
+ int* _Nonnull releaseFence) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
+ int ret = mDriver->unlock(buffer, releaseFence);
+ if (ret) {
+ ALOGE("Failed to unlock.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::flushLockedBuffer(buffer_handle_t _Nonnull buffer) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
+ int ret = mDriver->flush(buffer);
+ if (ret) {
+ ALOGE("Failed to flushLockedBuffer. Flush failed.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::rereadLockedBuffer(buffer_handle_t _Nonnull buffer) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
+ int ret = mDriver->invalidate(buffer);
+ if (ret) {
+ ALOGE("Failed to rereadLockedBuffer. Failed to invalidate.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ return AIMAPPER_ERROR_NONE;
+}
+
+int32_t CrosGrallocMapperV5::getMetadata(buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType, void* _Nonnull outData,
+ size_t outDataSize) {
+ // We don't have any vendor-specific metadata, so divert to getStandardMetadata after validating
+ // that this is a standard metadata request
+ if (isStandardMetadata(metadataType)) {
+ return getStandardMetadata(buffer, metadataType.value, outData, outDataSize);
+ }
+ return -AIMAPPER_ERROR_UNSUPPORTED;
+}
+
+int32_t CrosGrallocMapperV5::getStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
+ int64_t standardType, void* _Nonnull outData,
+ size_t outDataSize) {
+ // Can't use VALIDATE_DRIVER_AND_BUFFER_HANDLE because we need to negate the error
+ // for this call
+ if (!mDriver) {
+ ALOGE("Failed to %s. Driver is uninitialized.", __func__);
+ return -AIMAPPER_ERROR_NO_RESOURCES;
+ }
+ if (!(bufferHandle)) {
+ ALOGE("Failed to %s. Null buffer_handle_t.", __func__);
+ return -AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ ALOGE("Failed to get. Invalid handle.");
+ return -AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ int32_t retValue = -AIMAPPER_ERROR_UNSUPPORTED;
+ mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
+ auto provider = [&]<StandardMetadataType T>(auto&& provide) -> int32_t {
+ return getStandardMetadata(crosBuffer, provide, StandardMetadata<T>{});
+ };
+ retValue = provideStandardMetadata(static_cast<StandardMetadataType>(standardType), outData,
+ outDataSize, provider);
+ });
+ return retValue;
+}
+
+template <typename F, StandardMetadataType metadataType>
+int32_t CrosGrallocMapperV5::getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
+ StandardMetadata<metadataType>) {
+ const CrosGralloc4Metadata* crosMetadata = nullptr;
+ if constexpr (metadataType == StandardMetadataType::BLEND_MODE ||
+ metadataType == StandardMetadataType::CTA861_3 ||
+ metadataType == StandardMetadataType::DATASPACE ||
+ metadataType == StandardMetadataType::NAME ||
+ metadataType == StandardMetadataType::SMPTE2086) {
+ AIMapper_Error error = getCrosMetadata(crosBuffer, &crosMetadata);
+ if (error != AIMAPPER_ERROR_NONE) {
+ ALOGE("Failed to get. Failed to get buffer metadata.");
+ return -AIMAPPER_ERROR_NO_RESOURCES;
+ }
+ }
+ if constexpr (metadataType == StandardMetadataType::BUFFER_ID) {
+ return provide(crosBuffer->get_id());
+ }
+ if constexpr (metadataType == StandardMetadataType::NAME) {
+ return provide(crosMetadata->name);
+ }
+ if constexpr (metadataType == StandardMetadataType::WIDTH) {
+ return provide(crosBuffer->get_width());
+ }
+ if constexpr (metadataType == StandardMetadataType::STRIDE) {
+ return provide(crosBuffer->get_pixel_stride());
+ }
+ if constexpr (metadataType == StandardMetadataType::HEIGHT) {
+ return provide(crosBuffer->get_height());
+ }
+ if constexpr (metadataType == StandardMetadataType::LAYER_COUNT) {
+ return provide(1);
+ }
+ if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_REQUESTED) {
+ return provide(static_cast<PixelFormat>(crosBuffer->get_android_format()));
+ }
+ if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_FOURCC) {
+ return provide(drv_get_standard_fourcc(crosBuffer->get_format()));
+ }
+ if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_MODIFIER) {
+ return provide(crosBuffer->get_format_modifier());
+ }
+ if constexpr (metadataType == StandardMetadataType::USAGE) {
+ return provide(static_cast<BufferUsage>(crosBuffer->get_android_usage()));
+ }
+ if constexpr (metadataType == StandardMetadataType::ALLOCATION_SIZE) {
+ return provide(crosBuffer->get_total_size());
+ }
+ if constexpr (metadataType == StandardMetadataType::PROTECTED_CONTENT) {
+ uint64_t hasProtectedContent =
+ crosBuffer->get_android_usage() & static_cast<int64_t>(BufferUsage::PROTECTED) ? 1
+ : 0;
+ return provide(hasProtectedContent);
+ }
+ if constexpr (metadataType == StandardMetadataType::COMPRESSION) {
+ return provide(android::gralloc4::Compression_None);
+ }
+ if constexpr (metadataType == StandardMetadataType::INTERLACED) {
+ return provide(android::gralloc4::Interlaced_None);
+ }
+ if constexpr (metadataType == StandardMetadataType::CHROMA_SITING) {
+ return provide(android::gralloc4::ChromaSiting_None);
+ }
+ if constexpr (metadataType == StandardMetadataType::PLANE_LAYOUTS) {
+ std::vector<PlaneLayout> planeLayouts;
+ getPlaneLayouts(crosBuffer->get_format(), &planeLayouts);
+
+ for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
+ PlaneLayout& planeLayout = planeLayouts[plane];
+ planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane);
+ planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane);
+ planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane);
+ planeLayout.widthInSamples =
+ crosBuffer->get_width() / planeLayout.horizontalSubsampling;
+ planeLayout.heightInSamples =
+ crosBuffer->get_height() / planeLayout.verticalSubsampling;
+ }
+
+ return provide(planeLayouts);
+ }
+ if constexpr (metadataType == StandardMetadataType::CROP) {
+ const uint32_t numPlanes = crosBuffer->get_num_planes();
+ const uint32_t w = crosBuffer->get_width();
+ const uint32_t h = crosBuffer->get_height();
+ std::vector<aidl::android::hardware::graphics::common::Rect> crops;
+ for (uint32_t plane = 0; plane < numPlanes; plane++) {
+ aidl::android::hardware::graphics::common::Rect crop;
+ crop.left = 0;
+ crop.top = 0;
+ crop.right = w;
+ crop.bottom = h;
+ crops.push_back(crop);
+ }
+
+ return provide(crops);
+ }
+ if constexpr (metadataType == StandardMetadataType::DATASPACE) {
+ return provide(crosMetadata->dataspace);
+ }
+ if constexpr (metadataType == StandardMetadataType::BLEND_MODE) {
+ return provide(crosMetadata->blendMode);
+ }
+ if constexpr (metadataType == StandardMetadataType::SMPTE2086) {
+ return crosMetadata->smpte2086 ? provide(*crosMetadata->smpte2086) : 0;
+ }
+ if constexpr (metadataType == StandardMetadataType::CTA861_3) {
+ return crosMetadata->cta861_3 ? provide(*crosMetadata->cta861_3) : 0;
+ }
+ return -AIMAPPER_ERROR_UNSUPPORTED;
+}
+
+AIMapper_Error CrosGrallocMapperV5::setMetadata(buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType,
+ const void* _Nonnull metadata,
+ size_t metadataSize) {
+ // We don't have any vendor-specific metadata, so divert to setStandardMetadata after validating
+ // that this is a standard metadata request
+ if (isStandardMetadata(metadataType)) {
+ return setStandardMetadata(buffer, metadataType.value, metadata, metadataSize);
+ }
+ return AIMAPPER_ERROR_UNSUPPORTED;
+}
+
+AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
+ int64_t standardTypeRaw,
+ const void* _Nonnull metadata,
+ size_t metadataSize) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ ALOGE("Failed to get. Invalid handle.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ auto standardType = static_cast<StandardMetadataType>(standardTypeRaw);
+
+ switch (standardType) {
+ // Read-only values
+ case StandardMetadataType::BUFFER_ID:
+ case StandardMetadataType::NAME:
+ case StandardMetadataType::WIDTH:
+ case StandardMetadataType::HEIGHT:
+ case StandardMetadataType::LAYER_COUNT:
+ case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
+ case StandardMetadataType::USAGE:
+ return AIMAPPER_ERROR_BAD_VALUE;
+
+ // Supported to set
+ case StandardMetadataType::BLEND_MODE:
+ case StandardMetadataType::CTA861_3:
+ case StandardMetadataType::DATASPACE:
+ case StandardMetadataType::SMPTE2086:
+ break;
+
+ // Everything else unsupported
+ default:
+ return AIMAPPER_ERROR_UNSUPPORTED;
+ }
+
+ AIMapper_Error status = AIMAPPER_ERROR_UNSUPPORTED;
+ mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
+ CrosGralloc4Metadata* crosMetadata = nullptr;
+ status = getMutableCrosMetadata(crosBuffer, &crosMetadata);
+ if (status != AIMAPPER_ERROR_NONE) {
+ return;
+ }
+
+ auto applier = [&]<StandardMetadataType T>(auto&& value) -> AIMapper_Error {
+ return setStandardMetadata<T>(crosMetadata, std::forward<decltype(value)>(value));
+ };
+
+ status = applyStandardMetadata(standardType, metadata, metadataSize, applier);
+ });
+ return status;
+}
+
+template <StandardMetadataType TYPE>
+AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(
+ CrosGralloc4Metadata* crosMetadata, typename StandardMetadata<TYPE>::value_type&& value) {
+ if constexpr (TYPE == StandardMetadataType::BLEND_MODE) {
+ crosMetadata->blendMode = value;
+ }
+ if constexpr (TYPE == StandardMetadataType::CTA861_3) {
+ crosMetadata->cta861_3 = value;
+ }
+ if constexpr (TYPE == StandardMetadataType::DATASPACE) {
+ crosMetadata->dataspace = value;
+ }
+ if constexpr (TYPE == StandardMetadataType::SMPTE2086) {
+ crosMetadata->smpte2086 = value;
+ }
+ // Unsupported metadatas were already filtered before we reached this point
+ return AIMAPPER_ERROR_NONE;
+}
+
+constexpr AIMapper_MetadataTypeDescription describeStandard(StandardMetadataType type,
+ bool isGettable, bool isSettable) {
+ return {{STANDARD_METADATA_NAME, static_cast<int64_t>(type)},
+ nullptr,
+ isGettable,
+ isSettable,
+ {0}};
+}
+
+AIMapper_Error CrosGrallocMapperV5::listSupportedMetadataTypes(
+ const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+ size_t* _Nonnull outNumberOfDescriptions) {
+ static constexpr std::array<AIMapper_MetadataTypeDescription, 22> sSupportedMetadaTypes{
+ describeStandard(StandardMetadataType::BUFFER_ID, true, false),
+ describeStandard(StandardMetadataType::NAME, true, false),
+ describeStandard(StandardMetadataType::WIDTH, true, false),
+ describeStandard(StandardMetadataType::HEIGHT, true, false),
+ describeStandard(StandardMetadataType::LAYER_COUNT, true, false),
+ describeStandard(StandardMetadataType::PIXEL_FORMAT_REQUESTED, true, false),
+ describeStandard(StandardMetadataType::PIXEL_FORMAT_FOURCC, true, false),
+ describeStandard(StandardMetadataType::PIXEL_FORMAT_MODIFIER, true, false),
+ describeStandard(StandardMetadataType::USAGE, true, false),
+ describeStandard(StandardMetadataType::ALLOCATION_SIZE, true, false),
+ describeStandard(StandardMetadataType::PROTECTED_CONTENT, true, false),
+ describeStandard(StandardMetadataType::COMPRESSION, true, false),
+ describeStandard(StandardMetadataType::INTERLACED, true, false),
+ describeStandard(StandardMetadataType::CHROMA_SITING, true, false),
+ describeStandard(StandardMetadataType::PLANE_LAYOUTS, true, false),
+ describeStandard(StandardMetadataType::CROP, true, false),
+ describeStandard(StandardMetadataType::DATASPACE, true, true),
+ describeStandard(StandardMetadataType::COMPRESSION, true, false),
+ describeStandard(StandardMetadataType::BLEND_MODE, true, true),
+ describeStandard(StandardMetadataType::SMPTE2086, true, true),
+ describeStandard(StandardMetadataType::CTA861_3, true, true),
+ describeStandard(StandardMetadataType::STRIDE, true, false),
+ };
+ *outDescriptionList = sSupportedMetadaTypes.data();
+ *outNumberOfDescriptions = sSupportedMetadaTypes.size();
+ return AIMAPPER_ERROR_NONE;
+}
+
+void CrosGrallocMapperV5::dumpBuffer(
+ const cros_gralloc_buffer* crosBuffer,
+ std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback) {
+ // Temp buffer of ~10kb, should be large enough for any of the metadata we want to dump
+ std::vector<uint8_t> tempBuffer;
+ tempBuffer.resize(10000);
+ AIMapper_MetadataType metadataType;
+ metadataType.name = STANDARD_METADATA_NAME;
+
+ // Take an instance of the empty StandardMetadat<T> class just to allow auto-deduction
+ // to happen as explicit template invocation on lambdas is ugly
+ auto dump = [&]<StandardMetadataType T>(StandardMetadata<T>) {
+ // Nested templated lambdas! Woo! But the cleanness of the result is worth it
+ // The outer lambda exists basically just to capture the StandardMetadataType that's
+ // being dumped, as the `provider` parameter of getStandardMetadata only knows
+ // the value_type that the enum maps to but not the enum value itself, which we need to
+ // construct the `AIMapper_MetadataType` to pass to the dump callback
+ auto dumpInner = [&](const typename StandardMetadata<T>::value_type& value) -> int32_t {
+ int32_t size =
+ StandardMetadata<T>::value::encode(value, tempBuffer.data(), tempBuffer.size());
+ // The initial size should always be large enough, but just in case...
+ if (size > tempBuffer.size()) {
+ tempBuffer.resize(size * 2);
+ size = StandardMetadata<T>::value::encode(value, tempBuffer.data(),
+ tempBuffer.size());
+ }
+ // If the first resize failed _somehow_, just give up. Also don't notify if any
+ // errors occurred during encoding.
+ if (size >= 0 && size <= tempBuffer.size()) {
+ metadataType.value = static_cast<int64_t>(T);
+ callback(metadataType, tempBuffer);
+ }
+ // We don't actually care about the return value in this case, but why not use the
+ // real value anyway
+ return size;
+ };
+ getStandardMetadata(crosBuffer, dumpInner, StandardMetadata<T>{});
+ };
+
+ // So clean. So pretty.
+ dump(StandardMetadata<StandardMetadataType::BUFFER_ID>{});
+ dump(StandardMetadata<StandardMetadataType::NAME>{});
+ dump(StandardMetadata<StandardMetadataType::WIDTH>{});
+ dump(StandardMetadata<StandardMetadataType::HEIGHT>{});
+ dump(StandardMetadata<StandardMetadataType::LAYER_COUNT>{});
+ dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>{});
+ dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>{});
+ dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>{});
+ dump(StandardMetadata<StandardMetadataType::USAGE>{});
+ dump(StandardMetadata<StandardMetadataType::ALLOCATION_SIZE>{});
+ dump(StandardMetadata<StandardMetadataType::PROTECTED_CONTENT>{});
+ dump(StandardMetadata<StandardMetadataType::COMPRESSION>{});
+ dump(StandardMetadata<StandardMetadataType::INTERLACED>{});
+ dump(StandardMetadata<StandardMetadataType::CHROMA_SITING>{});
+ dump(StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>{});
+ dump(StandardMetadata<StandardMetadataType::DATASPACE>{});
+ dump(StandardMetadata<StandardMetadataType::BLEND_MODE>{});
+}
+
+AIMapper_Error CrosGrallocMapperV5::dumpBuffer(
+ buffer_handle_t _Nonnull bufferHandle,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ ALOGE("Failed to get. Invalid handle.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+ auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
+ dumpBufferCallback(context, type, buffer.data(), buffer.size());
+ };
+ mDriver->with_buffer(
+ crosHandle, [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, callback); });
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::dumpAllBuffers(
+ AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
+ REQUIRE_DRIVER()
+ auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
+ dumpBufferCallback(context, type, buffer.data(), buffer.size());
+ };
+ mDriver->with_each_buffer([&](cros_gralloc_buffer* crosBuffer) {
+ beginDumpBufferCallback(context);
+ dumpBuffer(crosBuffer, callback);
+ });
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::getReservedRegion(buffer_handle_t _Nonnull buffer,
+ void* _Nullable* _Nonnull outReservedRegion,
+ uint64_t* _Nonnull outReservedSize) {
+ VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(buffer);
+ if (!crosHandle) {
+ ALOGE("Failed to getReservedRegion. Invalid handle.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ void* reservedRegionAddr = nullptr;
+ uint64_t reservedRegionSize = 0;
+
+ AIMapper_Error error = AIMAPPER_ERROR_NONE;
+ mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
+ error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA,
+ &reservedRegionAddr, &reservedRegionSize);
+ });
+
+ if (error != AIMAPPER_ERROR_NONE) {
+ ALOGE("Failed to getReservedRegion. Failed to getReservedRegionArea.");
+ return AIMAPPER_ERROR_BAD_BUFFER;
+ }
+
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
+ ReservedRegionArea area, void** outAddr,
+ uint64_t* outSize) {
+ int ret = crosBuffer->get_reserved_region(outAddr, outSize);
+ if (ret) {
+ ALOGE("Failed to getReservedRegionArea.");
+ *outAddr = nullptr;
+ *outSize = 0;
+ return AIMAPPER_ERROR_NO_RESOURCES;
+ }
+
+ switch (area) {
+ case ReservedRegionArea::MAPPER4_METADATA: {
+ // CrosGralloc4Metadata resides at the beginning reserved region.
+ *outSize = sizeof(CrosGralloc4Metadata);
+ break;
+ }
+ case ReservedRegionArea::USER_METADATA: {
+ // User metadata resides after the CrosGralloc4Metadata.
+ *outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) +
+ sizeof(CrosGralloc4Metadata));
+ *outSize = *outSize - sizeof(CrosGralloc4Metadata);
+ break;
+ }
+ }
+
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
+ const CrosGralloc4Metadata** outMetadata) {
+ void* addr = nullptr;
+ uint64_t size;
+
+ auto error =
+ getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
+ if (error != AIMAPPER_ERROR_NONE) {
+ return error;
+ }
+
+ *outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr);
+ return AIMAPPER_ERROR_NONE;
+}
+
+AIMapper_Error CrosGrallocMapperV5::getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
+ CrosGralloc4Metadata** outMetadata) {
+ void* addr = nullptr;
+ uint64_t size;
+
+ auto error =
+ getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
+ if (error != AIMAPPER_ERROR_NONE) {
+ return error;
+ }
+
+ *outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
+ return AIMAPPER_ERROR_NONE;
+}
+
+extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
+
+extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
+ static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
+ return provider.load(outImplementation);
+} \ No newline at end of file
diff --git a/cros_gralloc/mapper_stablec/mapper.minigbm.xml b/cros_gralloc/mapper_stablec/mapper.minigbm.xml
new file mode 100644
index 0000000..282f7c8
--- /dev/null
+++ b/cros_gralloc/mapper_stablec/mapper.minigbm.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="device">
+ <hal format="native">
+ <name>mapper</name>
+ <version>5.0</version>
+ <interface>
+ <instance>minigbm</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/dri.c b/dri.c
index 7257c31..5a30a77 100644
--- a/dri.c
+++ b/dri.c
@@ -78,7 +78,7 @@ static void close_gem_handle(uint32_t handle, int fd)
gem_close.handle = handle;
ret = drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
if (ret)
- drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", handle, ret);
+ drv_loge("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", handle, ret);
}
/*
@@ -135,7 +135,7 @@ static int import_into_minigbm(struct dri_driver *dri, struct bo *bo)
close(prime_fd);
if (ret) {
- drv_log("drmPrimeFDToHandle failed with %s\n", strerror(errno));
+ drv_loge("drmPrimeFDToHandle failed with %s\n", strerror(errno));
goto cleanup;
}
@@ -186,6 +186,20 @@ cleanup:
return ret;
}
+const __DRIuseInvalidateExtension use_invalidate = {
+ .base = { __DRI_USE_INVALIDATE, 1 },
+};
+
+void *dri_dlopen(const char *dri_so_path)
+{
+ return dlopen(dri_so_path, RTLD_NOW | RTLD_GLOBAL);
+}
+
+void dri_dlclose(void *dri_so_handle)
+{
+ dlclose(dri_so_handle);
+}
+
/*
* The caller is responsible for setting drv->priv to a structure that derives from dri_driver.
*/
@@ -193,7 +207,7 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf
{
char fname[128];
const __DRIextension **(*get_extensions)();
- const __DRIextension *loader_extensions[] = { NULL };
+ const __DRIextension *loader_extensions[] = { &use_invalidate.base, NULL };
struct dri_driver *dri = drv->priv;
char *node_name = drmGetRenderDeviceNameFromFd(drv_get_fd(drv));
@@ -205,7 +219,7 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf
if (dri->fd < 0)
return -ENODEV;
- dri->driver_handle = dlopen(dri_so_path, RTLD_NOW | RTLD_GLOBAL);
+ dri->driver_handle = dri_dlopen(dri_so_path);
if (!dri->driver_handle)
goto close_dri_fd;
@@ -253,7 +267,7 @@ free_context:
free_screen:
dri->core_extension->destroyScreen(dri->device);
free_handle:
- dlclose(dri->driver_handle);
+ dri_dlclose(dri->driver_handle);
dri->driver_handle = NULL;
close_dri_fd:
close(dri->fd);
@@ -269,7 +283,7 @@ void dri_close(struct driver *drv)
dri->core_extension->destroyContext(dri->context);
dri->core_extension->destroyScreen(dri->device);
- dlclose(dri->driver_handle);
+ dri_dlclose(dri->driver_handle);
dri->driver_handle = NULL;
close(dri->fd);
}
diff --git a/dri.h b/dri.h
index daadf30..8136f5c 100644
--- a/dri.h
+++ b/dri.h
@@ -26,6 +26,9 @@ struct dri_driver {
const __DRIconfig **configs;
};
+void *dri_dlopen(const char *dri_so_path);
+void dri_dlclose(void *dri_so_handle);
+
int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suffix);
void dri_close(struct driver *drv);
int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
diff --git a/drv.c b/drv.c
index ada02ba..cbd7b4b 100644
--- a/drv.c
+++ b/drv.c
@@ -30,15 +30,9 @@ extern const struct backend backend_amdgpu;
#ifdef DRV_I915
extern const struct backend backend_i915;
#endif
-#ifdef DRV_MEDIATEK
-extern const struct backend backend_mediatek;
-#endif
#ifdef DRV_MSM
extern const struct backend backend_msm;
#endif
-#ifdef DRV_ROCKCHIP
-extern const struct backend backend_rockchip;
-#endif
#ifdef DRV_VC4
extern const struct backend backend_vc4;
#endif
@@ -46,15 +40,47 @@ extern const struct backend backend_vc4;
// Dumb / generic drivers
extern const struct backend backend_evdi;
extern const struct backend backend_marvell;
+extern const struct backend backend_mediatek;
extern const struct backend backend_meson;
extern const struct backend backend_nouveau;
extern const struct backend backend_komeda;
extern const struct backend backend_radeon;
+extern const struct backend backend_rockchip;
+extern const struct backend backend_sun4i_drm;
extern const struct backend backend_synaptics;
extern const struct backend backend_virtgpu;
extern const struct backend backend_udl;
extern const struct backend backend_vkms;
+static const struct backend *drv_backend_list[] = {
+#ifdef DRV_AMDGPU
+ &backend_amdgpu,
+#endif
+#ifdef DRV_I915
+ &backend_i915,
+#endif
+#ifdef DRV_MSM
+ &backend_msm,
+#endif
+#ifdef DRV_VC4
+ &backend_vc4,
+#endif
+ &backend_evdi, &backend_komeda, &backend_marvell, &backend_mediatek,
+ &backend_meson, &backend_nouveau, &backend_radeon, &backend_rockchip,
+ &backend_sun4i_drm, &backend_synaptics, &backend_udl, &backend_virtgpu,
+ &backend_vkms
+};
+
+void drv_preload(bool load)
+{
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
+ const struct backend *b = drv_backend_list[i];
+ if (b->preload)
+ b->preload(load);
+ }
+}
+
static const struct backend *drv_get_backend(int fd)
{
drmVersionPtr drm_version;
@@ -65,32 +91,8 @@ static const struct backend *drv_get_backend(int fd)
if (!drm_version)
return NULL;
- const struct backend *backend_list[] = {
-#ifdef DRV_AMDGPU
- &backend_amdgpu,
-#endif
-#ifdef DRV_I915
- &backend_i915,
-#endif
-#ifdef DRV_MEDIATEK
- &backend_mediatek,
-#endif
-#ifdef DRV_MSM
- &backend_msm,
-#endif
-#ifdef DRV_ROCKCHIP
- &backend_rockchip,
-#endif
-#ifdef DRV_VC4
- &backend_vc4,
-#endif
- &backend_evdi, &backend_marvell, &backend_meson, &backend_nouveau,
- &backend_komeda, &backend_radeon, &backend_synaptics, &backend_virtgpu,
- &backend_udl, &backend_virtgpu, &backend_vkms
- };
-
- for (i = 0; i < ARRAY_SIZE(backend_list); i++) {
- const struct backend *b = backend_list[i];
+ for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
+ const struct backend *b = drv_backend_list[i];
if (!strcmp(drm_version->name, b->name)) {
drmFreeVersion(drm_version);
return b;
@@ -258,7 +260,7 @@ static void drv_bo_mapping_destroy(struct bo *bo)
if (ret) {
pthread_mutex_unlock(&drv->mappings_lock);
assert(ret);
- drv_log("munmap failed\n");
+ drv_loge("munmap failed\n");
return;
}
@@ -438,7 +440,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
seek_end = lseek(data->fds[plane], 0, SEEK_END);
if (seek_end == (off_t)(-1)) {
- drv_log("lseek() failed with %s\n", strerror(errno));
+ drv_loge("lseek() failed with %s\n", strerror(errno));
goto destroy_bo;
}
@@ -449,7 +451,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
bo->meta.sizes[plane] = data->offsets[plane + 1] - data->offsets[plane];
if ((int64_t)bo->meta.offsets[plane] + bo->meta.sizes[plane] > seek_end) {
- drv_log("buffer size is too large.\n");
+ drv_loge("buffer size is too large.\n");
goto destroy_bo;
}
@@ -521,7 +523,7 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags
}
memcpy(mapping.vma->map_strides, bo->meta.strides, sizeof(mapping.vma->map_strides));
- addr = drv->backend->bo_map(bo, mapping.vma, plane, map_flags);
+ addr = drv->backend->bo_map(bo, mapping.vma, map_flags);
if (addr == MAP_FAILED) {
*map_data = NULL;
free(mapping.vma);
@@ -660,7 +662,7 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane)
ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC, &fd);
if (ret)
- drv_log("Failed to get plane fd: %s\n", strerror(errno));
+ drv_loge("Failed to get plane fd: %s\n", strerror(errno));
return (ret) ? ret : fd;
}
@@ -744,7 +746,8 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo)
return count;
}
-void drv_log_prefix(const char *prefix, const char *file, int line, const char *format, ...)
+void drv_log_prefix(enum drv_log_level level, 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);
@@ -752,10 +755,30 @@ void drv_log_prefix(const char *prefix, const char *file, int line, const char *
va_list args;
va_start(args, format);
#ifdef __ANDROID__
- __android_log_vprint(ANDROID_LOG_ERROR, buf, format, args);
+ int prio = ANDROID_LOG_ERROR;
+ switch (level) {
+ case DRV_LOGV:
+ prio = ANDROID_LOG_VERBOSE;
+ break;
+ case DRV_LOGD:
+ prio = ANDROID_LOG_DEBUG;
+ break;
+ case DRV_LOGI:
+ prio = ANDROID_LOG_INFO;
+ break;
+ case DRV_LOGE:
+ default:
+ break;
+ };
+ __android_log_vprint(prio, buf, format, args);
#else
- fprintf(stderr, "%s ", buf);
- vfprintf(stderr, format, args);
+ if (level == DRV_LOGE) {
+ fprintf(stderr, "%s ", buf);
+ vfprintf(stderr, format, args);
+ } else {
+ fprintf(stdout, "%s ", buf);
+ vfprintf(stdout, format, args);
+ }
#endif
va_end(args);
}
diff --git a/drv.h b/drv.h
index 3dffdff..b824fc5 100644
--- a/drv.h
+++ b/drv.h
@@ -41,6 +41,9 @@ extern "C" {
#define BO_USE_FRONT_RENDERING (1ull << 16)
#define BO_USE_RENDERSCRIPT (1ull << 17)
#define BO_USE_GPU_DATA_BUFFER (1ull << 18)
+#define BO_USE_SENSOR_DIRECT_DATA (1ull << 19)
+
+#define BO_USE_ARC_SCREEN_CAP_PROBED (1ull << 63)
/* Quirks for allocating a buffer. */
#define BO_QUIRK_NONE 0
@@ -76,6 +79,10 @@ extern "C" {
#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
#endif
+//TODO: remove this defination once drm_fourcc.h contains it.
+#ifndef I915_FORMAT_MOD_4_TILED
+#define I915_FORMAT_MOD_4_TILED fourcc_mod_code(INTEL, 9)
+#endif
// clang-format on
struct driver;
struct bo;
@@ -124,6 +131,8 @@ struct mapping {
uint32_t refcount;
};
+void drv_preload(bool load);
+
struct driver *drv_create(int fd);
void drv_destroy(struct driver *drv);
@@ -206,12 +215,25 @@ int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES],
uint32_t drv_get_max_texture_2d_size(struct driver *drv);
-#define drv_log(format, ...) \
+enum drv_log_level {
+ DRV_LOGV,
+ DRV_LOGD,
+ DRV_LOGI,
+ DRV_LOGE,
+};
+
+#define _drv_log(level, format, ...) \
do { \
- drv_log_prefix("minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \
+ drv_log_prefix(level, "minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \
} while (0)
-__attribute__((format(printf, 4, 5))) void drv_log_prefix(const char *prefix, const char *file,
+#define drv_loge(format, ...) _drv_log(DRV_LOGE, format, ##__VA_ARGS__)
+#define drv_logv(format, ...) _drv_log(DRV_LOGV, format, ##__VA_ARGS__)
+#define drv_logd(format, ...) _drv_log(DRV_LOGD, format, ##__VA_ARGS__)
+#define drv_logi(format, ...) _drv_log(DRV_LOGI, format, ##__VA_ARGS__)
+
+__attribute__((format(printf, 5, 6))) void drv_log_prefix(enum drv_log_level level,
+ const char *prefix, const char *file,
int line, const char *format, ...);
#ifdef __cplusplus
diff --git a/drv_helpers.c b/drv_helpers.c
index 6ea4b8e..cd51881 100644
--- a/drv_helpers.c
+++ b/drv_helpers.c
@@ -163,7 +163,7 @@ static const struct planar_layout *layout_from_format(uint32_t format)
return &packed_8bpp_layout;
default:
- drv_log("UNKNOWN FORMAT %d\n", format);
+ drv_loge("UNKNOWN FORMAT %d\n", format);
return NULL;
}
}
@@ -250,18 +250,30 @@ uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height,
return stride * drv_height_from_format(format, height, plane);
}
-static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane)
+static uint32_t subsample_stride(uint32_t stride, uint32_t stride_align, uint32_t format,
+ size_t plane)
{
+ uint32_t plane_stride = stride;
+
if (plane != 0) {
switch (format) {
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YVU420_ANDROID:
- stride = DIV_ROUND_UP(stride, 2);
+ plane_stride = DIV_ROUND_UP(plane_stride, 2);
break;
}
}
- return stride;
+ plane_stride = ALIGN(plane_stride, stride_align);
+
+ if (format == DRM_FORMAT_YVU420_ANDROID) {
+ if (plane != 0)
+ assert(plane_stride == ALIGN(stride / 2, 16));
+ else
+ assert(plane_stride % 16 == 0);
+ }
+
+ return plane_stride;
}
/*
@@ -269,14 +281,17 @@ static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane)
* 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)
+int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t stride_align,
+ uint32_t aligned_height, uint32_t format)
{
uint32_t padding[DRV_MAX_PLANES] = { 0 };
- return drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding);
+ return drv_bo_from_format_and_padding(bo, stride, stride_align, aligned_height, format,
+ padding);
}
-int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t aligned_height,
- uint32_t format, uint32_t padding[DRV_MAX_PLANES])
+int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t stride_align,
+ uint32_t aligned_height, uint32_t format,
+ uint32_t padding[DRV_MAX_PLANES])
{
size_t p, num_planes;
uint32_t offset = 0;
@@ -287,16 +302,18 @@ int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t alig
/*
* 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.
+ * - the luma stride is 16 bytes aligned
+ * - the chroma stride is ALIGN(luma_stride / 2, 16)
*/
if (format == DRM_FORMAT_YVU420_ANDROID) {
assert(aligned_height == bo->meta.height);
- assert(stride == ALIGN(stride, 32));
+ /* force 16 if the caller has no requirement */
+ if (stride_align <= 1)
+ stride_align = 16;
}
for (p = 0; p < num_planes; p++) {
- bo->meta.strides[p] = subsample_stride(stride, format, p);
+ bo->meta.strides[p] = subsample_stride(stride, stride_align, format, p);
bo->meta.sizes[p] =
drv_size_from_format(format, bo->meta.strides[p], aligned_height, p) +
padding[p];
@@ -353,6 +370,9 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32
DIV_ROUND_UP(aligned_width * layout_from_format(format)->bytes_per_pixel[0], 4);
create_dumb.bpp = 32;
} else {
+ /* Align for llvmpipe 64-byte tile size for dumb_driver */
+ aligned_width = ALIGN(aligned_width, MESA_LLVMPIPE_TILE_SIZE);
+ aligned_height = ALIGN(aligned_height, MESA_LLVMPIPE_TILE_SIZE);
create_dumb.bpp = layout_from_format(format)->bytes_per_pixel[0] * 8;
}
create_dumb.width = aligned_width;
@@ -361,11 +381,11 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
if (ret) {
- drv_log("DRM_IOCTL_MODE_CREATE_DUMB failed (%d, %d)\n", bo->drv->fd, errno);
+ drv_loge("DRM_IOCTL_MODE_CREATE_DUMB failed (%d, %d)\n", bo->drv->fd, errno);
return -errno;
}
- drv_bo_from_format(bo, create_dumb.pitch, height, format);
+ drv_bo_from_format(bo, create_dumb.pitch, 1, height, format);
for (plane = 0; plane < bo->meta.num_planes; plane++)
bo->handles[plane].u32 = create_dumb.handle;
@@ -388,7 +408,7 @@ int drv_dumb_bo_destroy(struct bo *bo)
destroy_dumb.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
if (ret) {
- drv_log("DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", bo->handles[0].u32);
+ drv_loge("DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", bo->handles[0].u32);
return -errno;
}
@@ -414,8 +434,8 @@ int drv_gem_bo_destroy(struct bo *bo)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
if (ret) {
- drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n",
- bo->handles[plane].u32, ret);
+ drv_loge("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n",
+ bo->handles[plane].u32, ret);
error = -errno;
}
}
@@ -436,7 +456,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle);
if (ret) {
- drv_log("DRM_IOCTL_PRIME_FD_TO_HANDLE failed (fd=%u)\n", prime_handle.fd);
+ drv_loge("DRM_IOCTL_PRIME_FD_TO_HANDLE failed (fd=%u)\n", prime_handle.fd);
/*
* Need to call GEM close on planes that were opened,
@@ -456,24 +476,23 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data)
return 0;
}
-void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
size_t i;
struct drm_mode_map_dumb map_dumb;
memset(&map_dumb, 0, sizeof(map_dumb));
- map_dumb.handle = bo->handles[plane].u32;
+ map_dumb.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
if (ret) {
- drv_log("DRM_IOCTL_MODE_MAP_DUMB failed\n");
+ drv_loge("DRM_IOCTL_MODE_MAP_DUMB failed\n");
return MAP_FAILED;
}
for (i = 0; i < bo->meta.num_planes; i++)
- if (bo->handles[i].u32 == bo->handles[plane].u32)
- vma->length += bo->meta.sizes[i];
+ vma->length += bo->meta.sizes[i];
return mmap(0, vma->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
map_dumb.offset);
diff --git a/drv_helpers.h b/drv_helpers.h
index edb69bf..0ea9ba9 100644
--- a/drv_helpers.h
+++ b/drv_helpers.h
@@ -21,9 +21,11 @@ struct format_metadata;
uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane);
uint32_t drv_vertical_subsampling_from_format(uint32_t format, size_t plane);
uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane);
-int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, uint32_t format);
-int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t aligned_height,
- uint32_t format, uint32_t padding[DRV_MAX_PLANES]);
+int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t stride_align,
+ uint32_t aligned_height, uint32_t format);
+int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t stride_align,
+ uint32_t aligned_height, uint32_t format,
+ uint32_t padding[DRV_MAX_PLANES]);
int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
uint64_t use_flags);
int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
@@ -31,7 +33,7 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32
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 vma *vma, size_t plane, uint32_t map_flags);
+void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags);
int drv_bo_munmap(struct bo *bo, struct vma *vma);
int drv_get_prot(uint32_t map_flags);
void drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata,
diff --git a/drv_priv.h b/drv_priv.h
index d2da440..a2ccdda 100644
--- a/drv_priv.h
+++ b/drv_priv.h
@@ -74,6 +74,7 @@ struct driver {
struct backend {
char *name;
+ void (*preload)(bool load);
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,
@@ -90,7 +91,7 @@ struct backend {
/* Called on free if this bo is the last object referencing the contained GEM BOs */
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 vma *vma, size_t plane, uint32_t map_flags);
+ void *(*bo_map)(struct bo *bo, struct vma *vma, uint32_t map_flags);
int (*bo_unmap)(struct bo *bo, struct vma *vma);
int (*bo_invalidate)(struct bo *bo, struct mapping *mapping);
int (*bo_flush)(struct bo *bo, struct mapping *mapping);
@@ -115,14 +116,24 @@ struct backend {
#define BO_USE_SW_MASK (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_FRONT_RENDERING)
+#define BO_USE_GPU_HW (BO_USE_RENDERING | BO_USE_TEXTURE | BO_USE_GPU_DATA_BUFFER)
+
#define BO_USE_NON_GPU_HW (BO_USE_SCANOUT | BO_USE_CAMERA_WRITE | BO_USE_CAMERA_READ | \
- BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER)
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | BO_USE_SENSOR_DIRECT_DATA)
+
+#define BO_USE_HW_MASK (BO_USE_GPU_HW | BO_USE_NON_GPU_HW)
#ifndef DRM_FORMAT_MOD_LINEAR
#define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE
#endif
#define LINEAR_METADATA (struct format_metadata) { 1, 0, DRM_FORMAT_MOD_LINEAR }
+
+#define MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS 15
+#define MESA_LLVMPIPE_MAX_TEXTURE_2D_SIZE (1 << (MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS - 1))
+#define MESA_LLVMPIPE_TILE_ORDER 6
+#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER)
+
// clang-format on
#endif
diff --git a/dumb_driver.c b/dumb_driver.c
index c667a51..f74d237 100644
--- a/dumb_driver.c
+++ b/dumb_driver.c
@@ -10,9 +10,9 @@
#include "drv_priv.h"
#include "util.h"
-#define INIT_DUMB_DRIVER(driver) \
+#define INIT_DUMB_DRIVER_WITH_NAME(driver, _name) \
const struct backend backend_##driver = { \
- .name = #driver, \
+ .name = _name, \
.init = dumb_driver_init, \
.bo_create = drv_dumb_bo_create, \
.bo_create_with_modifiers = dumb_bo_create_with_modifiers, \
@@ -23,6 +23,8 @@
.resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, \
};
+#define INIT_DUMB_DRIVER(driver) INIT_DUMB_DRIVER_WITH_NAME(driver, #driver)
+
static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888,
DRM_FORMAT_ABGR8888, DRM_FORMAT_XBGR8888,
DRM_FORMAT_BGR888, DRM_FORMAT_RGB565 };
@@ -40,7 +42,8 @@ static int dumb_driver_init(struct driver *drv)
drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER |
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE |
+ BO_USE_GPU_DATA_BUFFER | BO_USE_SENSOR_DIRECT_DATA);
drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER |
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
@@ -67,6 +70,14 @@ INIT_DUMB_DRIVER(marvell)
INIT_DUMB_DRIVER(meson)
INIT_DUMB_DRIVER(nouveau)
INIT_DUMB_DRIVER(radeon)
+INIT_DUMB_DRIVER_WITH_NAME(sun4i_drm, "sun4i-drm")
INIT_DUMB_DRIVER(synaptics)
INIT_DUMB_DRIVER(udl)
INIT_DUMB_DRIVER(vkms)
+
+#ifndef DRV_ROCKCHIP
+INIT_DUMB_DRIVER(rockchip)
+#endif
+#ifndef DRV_MEDIATEK
+INIT_DUMB_DRIVER(mediatek)
+#endif
diff --git a/external/i915_drm.h b/external/i915_drm.h
index e301c5f..e009a9e 100644
--- a/external/i915_drm.h
+++ b/external/i915_drm.h
@@ -1306,7 +1306,8 @@ struct drm_i915_gem_caching {
#define I915_TILING_NONE 0
#define I915_TILING_X 1
#define I915_TILING_Y 2
-#define I915_TILING_LAST I915_TILING_Y
+#define I915_TILING_4 9
+#define I915_TILING_LAST I915_TILING_4
#define I915_BIT_6_SWIZZLE_NONE 0
#define I915_BIT_6_SWIZZLE_9 1
diff --git a/gbm.h b/gbm.h
index 9acfaa2..7fae11c 100644
--- a/gbm.h
+++ b/gbm.h
@@ -290,6 +290,21 @@ enum gbm_bo_flags {
* with pixel data.
*/
GBM_BO_USE_FRONT_RENDERING = (1 << 16),
+
+ /**
+ * (1 << 17) is reserved for RenderScript (deprecated in Android 12).
+ */
+
+ /**
+ * The buffer will be used as a shader storage or uniform buffer
+ * object.
+ */
+ GBM_BO_USE_GPU_DATA_BUFFER = (1 << 18),
+
+ /**
+ * The buffer will be used as a sensor direct report output.
+ */
+ GBM_BO_USE_SENSOR_DIRECT_DATA = (1 << 19),
};
int
diff --git a/gbm_helpers.c b/gbm_helpers.c
index 17dcf1f..e5bcb40 100644
--- a/gbm_helpers.c
+++ b/gbm_helpers.c
@@ -46,6 +46,10 @@ uint64_t gbm_convert_usage(uint32_t usage)
use_flags |= BO_USE_HW_VIDEO_ENCODER;
if (usage & GBM_BO_USE_FRONT_RENDERING)
use_flags |= BO_USE_FRONT_RENDERING;
+ if (usage & GBM_BO_USE_GPU_DATA_BUFFER)
+ use_flags |= BO_USE_GPU_DATA_BUFFER;
+ if (usage & GBM_BO_USE_SENSOR_DIRECT_DATA)
+ use_flags |= BO_USE_SENSOR_DIRECT_DATA;
return use_flags;
}
diff --git a/i915.c b/i915.c
index 35c45eb..8619580 100644
--- a/i915.c
+++ b/i915.c
@@ -44,18 +44,25 @@ static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_R
static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
+static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR };
+
struct modifier_support_t {
const uint64_t *order;
uint32_t count;
};
struct i915_device {
- uint32_t gen;
+ uint32_t graphics_version;
int32_t has_llc;
int32_t has_hw_protection;
struct modifier_support_t modifier;
int device_id;
- bool is_adlp;
+ bool is_xelpd;
+ /*TODO : cleanup is_mtl to avoid adding variables for every new platforms */
+ bool is_mtl;
+ int32_t num_fences_avail;
+ bool has_mmap_offset;
};
static void i915_info_from_device_id(struct i915_device *i915)
@@ -103,72 +110,91 @@ static void i915_info_from_device_id(struct i915_device *i915)
0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68,
0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908
};
- const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8,
- 0x46AA, 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1,
- 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3,
- 0x46D0, 0x46D1, 0x46D2 };
+ const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA,
+ 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, 0x46B2, 0x46B3,
+ 0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2 };
+
+ const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9 };
+
+ const uint16_t mtl_ids[] = { 0x7D40, 0x7D60, 0x7D45, 0x7D55, 0x7DD5 };
+
unsigned i;
- i915->gen = 4;
- i915->is_adlp = false;
+ i915->graphics_version = 4;
+ i915->is_xelpd = false;
+ i915->is_mtl = false;
for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
if (gen3_ids[i] == i915->device_id)
- i915->gen = 3;
+ i915->graphics_version = 3;
/* Gen 4 */
for (i = 0; i < ARRAY_SIZE(gen4_ids); i++)
if (gen4_ids[i] == i915->device_id)
- i915->gen = 4;
+ i915->graphics_version = 4;
/* Gen 5 */
for (i = 0; i < ARRAY_SIZE(gen5_ids); i++)
if (gen5_ids[i] == i915->device_id)
- i915->gen = 5;
+ i915->graphics_version = 5;
/* Gen 6 */
for (i = 0; i < ARRAY_SIZE(gen6_ids); i++)
if (gen6_ids[i] == i915->device_id)
- i915->gen = 6;
+ i915->graphics_version = 6;
/* Gen 7 */
for (i = 0; i < ARRAY_SIZE(gen7_ids); i++)
if (gen7_ids[i] == i915->device_id)
- i915->gen = 7;
+ i915->graphics_version = 7;
/* Gen 8 */
for (i = 0; i < ARRAY_SIZE(gen8_ids); i++)
if (gen8_ids[i] == i915->device_id)
- i915->gen = 8;
+ i915->graphics_version = 8;
/* Gen 9 */
for (i = 0; i < ARRAY_SIZE(gen9_ids); i++)
if (gen9_ids[i] == i915->device_id)
- i915->gen = 9;
+ i915->graphics_version = 9;
/* Gen 11 */
for (i = 0; i < ARRAY_SIZE(gen11_ids); i++)
if (gen11_ids[i] == i915->device_id)
- i915->gen = 11;
+ i915->graphics_version = 11;
/* Gen 12 */
for (i = 0; i < ARRAY_SIZE(gen12_ids); i++)
if (gen12_ids[i] == i915->device_id)
- i915->gen = 12;
+ i915->graphics_version = 12;
for (i = 0; i < ARRAY_SIZE(adlp_ids); i++)
if (adlp_ids[i] == i915->device_id) {
- i915->is_adlp = true;
- i915->gen = 12;
+ i915->is_xelpd = true;
+ i915->graphics_version = 12;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rplp_ids); i++)
+ if (rplp_ids[i] == i915->device_id) {
+ i915->is_xelpd = true;
+ i915->graphics_version = 12;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mtl_ids); i++)
+ if (mtl_ids[i] == i915->device_id) {
+ i915->graphics_version = 12;
+ i915->is_mtl = true;
}
}
static void i915_get_modifier_order(struct i915_device *i915)
{
- if (i915->gen == 12) {
+ if (i915->is_mtl) {
+ i915->modifier.order = xe_lpdp_modifier_order;
+ i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order);
+ } else if (i915->graphics_version == 12) {
i915->modifier.order = gen12_modifier_order;
i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
- }
- else if (i915->gen == 11) {
+ } else if (i915->graphics_version == 11) {
i915->modifier.order = gen11_modifier_order;
i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
} else {
@@ -229,7 +255,8 @@ static int i915_add_combinations(struct driver *drv)
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata_linear,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER |
+ BO_USE_SENSOR_DIRECT_DATA);
const uint64_t render_not_linear = unset_flags(render, linear_mask);
const uint64_t scanout_and_render_not_linear = render_not_linear | BO_USE_SCANOUT;
@@ -243,34 +270,57 @@ static int i915_add_combinations(struct driver *drv)
drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
&metadata_x_tiled, scanout_and_render_not_linear);
- struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
- .priority = 3,
- .modifier = I915_FORMAT_MOD_Y_TILED };
-
+ if (i915->is_mtl) {
+ struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4,
+ .priority = 3,
+ .modifier = I915_FORMAT_MOD_4_TILED };
+/* Support tile4 NV12 and P010 for libva */
+#ifdef I915_SCANOUT_4_TILED
+ const uint64_t nv12_usage =
+ BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
+ const uint64_t p010_usage =
+ BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected | BO_USE_SCANOUT;
+#else
+ const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
+ const uint64_t p010_usage = nv12_usage;
+#endif
+ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_4_tiled, nv12_usage);
+ drv_add_combination(drv, DRM_FORMAT_P010, &metadata_4_tiled, p010_usage);
+ drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
+ &metadata_4_tiled, render_not_linear);
+ drv_add_combinations(drv, scanout_render_formats,
+ ARRAY_SIZE(scanout_render_formats), &metadata_4_tiled,
+ render_not_linear);
+ } else {
+ struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
+ .priority = 3,
+ .modifier = I915_FORMAT_MOD_Y_TILED };
/* Support y-tiled NV12 and P010 for libva */
#ifdef I915_SCANOUT_Y_TILED
- const uint64_t nv12_usage =
- BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
- const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
- (i915->gen >= 11 ? BO_USE_SCANOUT : 0);
+ const uint64_t nv12_usage =
+ BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
+ const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER |
+ hw_protected |
+ (i915->graphics_version >= 11 ? BO_USE_SCANOUT : 0);
#else
- const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
- const uint64_t p010_usage = nv12_usage;
+ const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
+ const uint64_t p010_usage = nv12_usage;
#endif
- drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
- drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
-
- drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_y_tiled,
- render_not_linear);
-
- // Y-tiled scanout isn't available on old platforms so we add
- // |scanout_render_formats| without that USE flag.
- drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
- &metadata_y_tiled, render_not_linear);
+ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
+ drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
+ drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
+ &metadata_y_tiled, render_not_linear);
+ /* Y-tiled scanout isn't available on old platforms so we add
+ * |scanout_render_formats| without that USE flag.
+ */
+ drv_add_combinations(drv, scanout_render_formats,
+ ARRAY_SIZE(scanout_render_formats), &metadata_y_tiled,
+ render_not_linear);
+ }
return 0;
}
-static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
+static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling, uint32_t *stride,
uint32_t *aligned_height)
{
struct i915_device *i915 = bo->drv->priv;
@@ -296,7 +346,24 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid
#else
horizontal_alignment = 64;
#endif
- vertical_alignment = 4;
+ /*
+ * For R8 and height=1, we assume the surface will be used as a linear buffer blob
+ * (such as VkBuffer). The hardware allows vertical_alignment=1 only for non-tiled
+ * 1D surfaces, which covers the VkBuffer case. However, if the app uses the surface
+ * as a 2D image with height=1, then this code is buggy. For 2D images, the hardware
+ * requires a vertical_alignment >= 4, and underallocating with vertical_alignment=1
+ * will cause the GPU to read out-of-bounds.
+ *
+ * TODO: add a new DRM_FORMAT_BLOB format for this case, or further tighten up the
+ * constraints with GPU_DATA_BUFFER usage when the guest has migrated to use
+ * virtgpu_cross_domain backend which passes that flag through.
+ */
+ if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
+ vertical_alignment = 1;
+ } else {
+ vertical_alignment = 4;
+ }
+
break;
case I915_TILING_X:
@@ -305,7 +372,8 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid
break;
case I915_TILING_Y:
- if (i915->gen == 3) {
+ case I915_TILING_4:
+ if (i915->graphics_version == 3) {
horizontal_alignment = 512;
vertical_alignment = 8;
} else {
@@ -316,7 +384,7 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid
}
*aligned_height = ALIGN(*aligned_height, vertical_alignment);
- if (i915->gen > 3) {
+ if (i915->graphics_version > 3) {
*stride = ALIGN(*stride, horizontal_alignment);
} else {
while (*stride > horizontal_alignment)
@@ -325,7 +393,7 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid
*stride = horizontal_alignment;
}
- if (i915->gen <= 3 && *stride > 8192)
+ if (i915->graphics_version <= 3 && *stride > 8192)
return -EINVAL;
return 0;
@@ -345,7 +413,7 @@ static void i915_clflush(void *start, size_t size)
static int i915_init(struct driver *drv)
{
- int ret;
+ int ret, val;
struct i915_device *i915;
drm_i915_getparam_t get_param = { 0 };
@@ -357,11 +425,11 @@ static int i915_init(struct driver *drv)
get_param.value = &(i915->device_id);
ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
if (ret) {
- drv_log("Failed to get I915_PARAM_CHIPSET_ID\n");
+ drv_loge("Failed to get I915_PARAM_CHIPSET_ID\n");
free(i915);
return -EINVAL;
}
- /* must call before i915->gen is used anywhere else */
+ /* must call before i915->graphics_version is used anywhere else */
i915_info_from_device_id(i915);
i915_get_modifier_order(i915);
@@ -371,12 +439,34 @@ static int i915_init(struct driver *drv)
get_param.value = &i915->has_llc;
ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
if (ret) {
- drv_log("Failed to get I915_PARAM_HAS_LLC\n");
+ drv_loge("Failed to get I915_PARAM_HAS_LLC\n");
+ free(i915);
+ return -EINVAL;
+ }
+
+ memset(&get_param, 0, sizeof(get_param));
+ get_param.param = I915_PARAM_NUM_FENCES_AVAIL;
+ get_param.value = &i915->num_fences_avail;
+ ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
+ if (ret) {
+ drv_loge("Failed to get I915_PARAM_NUM_FENCES_AVAIL\n");
+ free(i915);
+ return -EINVAL;
+ }
+
+ memset(&get_param, 0, sizeof(get_param));
+ get_param.param = I915_PARAM_MMAP_GTT_VERSION;
+ get_param.value = &val;
+
+ ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
+ if (ret) {
+ drv_loge("Failed to get I915_PARAM_MMAP_GTT_VERSION\n");
free(i915);
return -EINVAL;
}
+ i915->has_mmap_offset = (val >= 4);
- if (i915->gen >= 12)
+ if (i915->graphics_version >= 12)
i915->has_hw_protection = 1;
drv->priv = i915;
@@ -395,7 +485,7 @@ static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
case DRM_FORMAT_NV12:
case DRM_FORMAT_P010:
case DRM_FORMAT_P016:
- return (i915->gen == 11 || i915->gen == 12) && plane == 1;
+ return (i915->graphics_version == 11 || i915->graphics_version == 12) && plane == 1;
}
return false;
}
@@ -417,7 +507,7 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u
if (bo->meta.tiling != I915_TILING_NONE)
assert(IS_ALIGNED(offset, pagesize));
- ret = i915_align_dimensions(bo, bo->meta.tiling, &stride, &plane_height);
+ ret = i915_align_dimensions(bo, format, bo->meta.tiling, &stride, &plane_height);
if (ret)
return ret;
@@ -441,8 +531,7 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u
return 0;
}
-static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format,
- uint64_t modifier)
+static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier)
{
size_t num_planes = drv_num_planes_from_format(format);
if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
@@ -459,7 +548,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
{
uint64_t modifier;
struct i915_device *i915 = bo->drv->priv;
- bool huge_bo = (i915->gen < 11) && (width > 4096);
+ bool huge_bo = (i915->graphics_version < 11) && (width > 4096);
if (modifiers) {
modifier =
@@ -505,7 +594,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
}
/* Prevent gen 8 and earlier from trying to use a tiling modifier */
- if (i915->gen <= 8 && format == DRM_FORMAT_ARGB8888) {
+ if (i915->graphics_version <= 8 && format == DRM_FORMAT_ARGB8888) {
modifier = DRM_FORMAT_MOD_LINEAR;
}
@@ -524,6 +613,9 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
bo->meta.tiling = I915_TILING_Y;
break;
+ case I915_FORMAT_MOD_4_TILED:
+ bo->meta.tiling = I915_TILING_4;
+ break;
}
bo->meta.format_modifier = modifier;
@@ -538,7 +630,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
* aligning to 32 bytes here.
*/
uint32_t stride = ALIGN(width, 32);
- drv_bo_from_format(bo, stride, height, format);
+ return drv_bo_from_format(bo, stride, 1, height, format);
} else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
/*
* For compressed surfaces, we need a color control surface
@@ -593,7 +685,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
height = ALIGN(drv_height_from_format(format, height, 0), 32);
- if (i915->is_adlp && (stride > 1)) {
+ if (i915->is_xelpd && (stride > 1)) {
stride = 1 << (32 - __builtin_clz(stride - 1));
height = ALIGN(drv_height_from_format(format, height, 0), 128);
}
@@ -616,7 +708,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
} else {
- i915_bo_from_format(bo, width, height, format);
+ return i915_bo_from_format(bo, width, height, format);
}
return 0;
}
@@ -642,8 +734,8 @@ static int i915_bo_create_from_metadata(struct bo *bo)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
if (ret) {
- drv_log("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
- create_ext.size, ret);
+ drv_loge("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
+ create_ext.size, ret);
return -errno;
}
@@ -653,7 +745,7 @@ static int i915_bo_create_from_metadata(struct bo *bo)
gem_create.size = bo->meta.total_size;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
if (ret) {
- drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
+ drv_loge("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
return -errno;
}
@@ -663,20 +755,24 @@ static int i915_bo_create_from_metadata(struct bo *bo)
for (plane = 0; plane < bo->meta.num_planes; plane++)
bo->handles[plane].u32 = gem_handle;
- gem_set_tiling.handle = bo->handles[0].u32;
- gem_set_tiling.tiling_mode = bo->meta.tiling;
- gem_set_tiling.stride = bo->meta.strides[0];
+ /* Set/Get tiling ioctl not supported based on fence availability
+ Refer : "https://patchwork.freedesktop.org/patch/325343/"
+ */
+ if (i915->num_fences_avail) {
+ gem_set_tiling.handle = bo->handles[0].u32;
+ gem_set_tiling.tiling_mode = bo->meta.tiling;
+ gem_set_tiling.stride = bo->meta.strides[0];
- ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
- if (ret) {
- struct drm_gem_close gem_close = { 0 };
- gem_close.handle = bo->handles[0].u32;
- drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
+ if (ret) {
+ struct drm_gem_close gem_close = { 0 };
+ gem_close.handle = bo->handles[0].u32;
+ drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
- drv_log("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
- return -errno;
+ drv_loge("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
+ return -errno;
+ }
}
-
return 0;
}
@@ -690,68 +786,85 @@ static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
{
int ret;
struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
+ struct i915_device *i915 = bo->drv->priv;
- bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, data->format,
- data->format_modifier);
+ bo->meta.num_planes =
+ i915_num_planes_from_modifier(bo->drv, data->format, data->format_modifier);
ret = drv_prime_bo_import(bo, data);
if (ret)
return ret;
- /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
- gem_get_tiling.handle = bo->handles[0].u32;
+ /* Set/Get tiling ioctl not supported based on fence availability
+ Refer : "https://patchwork.freedesktop.org/patch/325343/"
+ */
+ if (i915->num_fences_avail) {
+ /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
+ gem_get_tiling.handle = bo->handles[0].u32;
- ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
- if (ret) {
- drv_gem_bo_destroy(bo);
- drv_log("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
- return ret;
+ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
+ if (ret) {
+ drv_gem_bo_destroy(bo);
+ drv_loge("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
+ return ret;
+ }
+ bo->meta.tiling = gem_get_tiling.tiling_mode;
}
-
- bo->meta.tiling = gem_get_tiling.tiling_mode;
return 0;
}
-static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
void *addr = MAP_FAILED;
+ struct i915_device *i915 = bo->drv->priv;
- if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS)
- return MAP_FAILED;
-
- if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS)
+ if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
+ (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
+ (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED))
return MAP_FAILED;
if (bo->meta.tiling == I915_TILING_NONE) {
- struct drm_i915_gem_mmap gem_map = { 0 };
- /* TODO(b/118799155): We don't seem to have a good way to
- * detect the use cases for which WC mapping is really needed.
- * The current heuristic seems overly coarse and may be slowing
- * down some other use cases unnecessarily.
- *
- * For now, care must be taken not to use WC mappings for
- * Renderscript and camera use cases, as they're
- * performance-sensitive. */
- if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
- !(bo->meta.use_flags &
- (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
- gem_map.flags = I915_MMAP_WC;
-
- gem_map.handle = bo->handles[0].u32;
- gem_map.offset = 0;
- gem_map.size = bo->meta.total_size;
-
- ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
- /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
- * file and returns a user space address directly, ie,
- * doesn't go through mmap. If we try that on a
- * dma-buf that doesn't have a shm file, i915.ko
- * returns ENXIO. Fall through to
- * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
- * will mmap on the drm fd instead. */
- if (ret == 0)
- addr = (void *)(uintptr_t)gem_map.addr_ptr;
+ if (i915->has_mmap_offset) {
+ struct drm_i915_gem_mmap_offset gem_map = { 0 };
+ gem_map.handle = bo->handles[0].u32;
+ gem_map.flags = I915_MMAP_OFFSET_WB;
+
+ /* Get the fake offset back */
+ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &gem_map);
+ if (ret == 0)
+ addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags),
+ MAP_SHARED, bo->drv->fd, gem_map.offset);
+ } else {
+ struct drm_i915_gem_mmap gem_map = { 0 };
+ /* TODO(b/118799155): We don't seem to have a good way to
+ * detect the use cases for which WC mapping is really needed.
+ * The current heuristic seems overly coarse and may be slowing
+ * down some other use cases unnecessarily.
+ *
+ * For now, care must be taken not to use WC mappings for
+ * Renderscript and camera use cases, as they're
+ * performance-sensitive. */
+ if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
+ !(bo->meta.use_flags &
+ (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
+ gem_map.flags = I915_MMAP_WC;
+
+ gem_map.handle = bo->handles[0].u32;
+ gem_map.offset = 0;
+ gem_map.size = bo->meta.total_size;
+
+ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
+ /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
+ * file and returns a user space address directly, ie,
+ * doesn't go through mmap. If we try that on a
+ * dma-buf that doesn't have a shm file, i915.ko
+ * returns ENXIO. Fall through to
+ * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
+ * will mmap on the drm fd instead. */
+ if (ret == 0)
+ addr = (void *)(uintptr_t)gem_map.addr_ptr;
+ }
}
if (addr == MAP_FAILED) {
@@ -760,7 +873,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t
gem_map.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
+ drv_loge("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
return MAP_FAILED;
}
@@ -769,7 +882,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t
}
if (addr == MAP_FAILED) {
- drv_log("i915 GEM mmap failed\n");
+ drv_loge("i915 GEM mmap failed\n");
return addr;
}
@@ -795,7 +908,7 @@ static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
if (ret) {
- drv_log("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
+ drv_loge("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
return ret;
}
diff --git a/mediatek.c b/mediatek.c
index 562b1d1..113273b 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -25,17 +25,34 @@
#define TILE_TYPE_LINEAR 0
-#if defined(MTK_MT8183) || defined(MTK_MT8186)
-#define SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
+// clang-format off
+#if defined(MTK_MT8183) || \
+ defined(MTK_MT8186)
+// clang-format on
+#define SUPPORTS_YUV422
#endif
// All platforms except MT8173 should USE_NV12_FOR_HW_VIDEO_DECODING.
-#if defined(MTK_MT8183) || defined(MTK_MT8186) || defined(MTK_MT8192) || defined(MTK_MT8195)
+// clang-format off
+#if defined(MTK_MT8183) || \
+ defined(MTK_MT8186) || \
+ defined(MTK_MT8188G) || \
+ defined(MTK_MT8192) || \
+ defined(MTK_MT8195)
+// clang-format on
#define USE_NV12_FOR_HW_VIDEO_DECODING
#else
#define DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS
#endif
+// For Mali Sigurd based GPUs, the texture unit reads outside the specified texture dimensions.
+// Therefore, certain formats require extra memory padding to its allocated surface to prevent the
+// hardware from reading outside an allocation. For YVU420, we need additional padding for the last
+// chroma plane.
+#if defined(MTK_MT8186)
+#define USE_EXTRA_PADDING_FOR_YVU420
+#endif
+
struct mediatek_private_map_data {
void *cached_addr;
void *gem_addr;
@@ -48,12 +65,12 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA
// clang-format off
static const uint32_t texture_source_formats[] = {
-#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
+#ifdef SUPPORTS_YUV422
DRM_FORMAT_NV21,
DRM_FORMAT_YUYV,
+#endif
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_ABGR16161616F,
-#endif
DRM_FORMAT_NV12,
DRM_FORMAT_YVU420,
DRM_FORMAT_YVU420_ANDROID
@@ -62,6 +79,7 @@ static const uint32_t texture_source_formats[] = {
static const uint32_t video_yuv_formats[] = {
DRM_FORMAT_NV21,
DRM_FORMAT_NV12,
+ DRM_FORMAT_YUYV,
DRM_FORMAT_YVU420,
DRM_FORMAT_YVU420_ANDROID
};
@@ -89,6 +107,11 @@ static int mediatek_init(struct driver *drv)
drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_SW_MASK | BO_USE_LINEAR);
+ /* YUYV format for video overlay and camera subsystem. */
+ drv_add_combination(drv, DRM_FORMAT_YUYV, &LINEAR_METADATA,
+ BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | BO_USE_LINEAR |
+ BO_USE_TEXTURE);
+
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
@@ -109,7 +132,8 @@ static int mediatek_init(struct driver *drv)
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE |
+ BO_USE_GPU_DATA_BUFFER | BO_USE_SENSOR_DIRECT_DATA);
/* NV12 format for encoding and display. */
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
@@ -149,7 +173,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) {
errno = EINVAL;
- drv_log("no usable modifier found\n");
+ drv_loge("no usable modifier found\n");
return -EINVAL;
}
@@ -177,9 +201,9 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
(32 / drv_vertical_subsampling_from_format(format, plane));
}
- drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding);
+ drv_bo_from_format_and_padding(bo, stride, 1, aligned_height, format, padding);
} else {
-#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
+#ifdef SUPPORTS_YUV422
/*
* JPEG Encoder Accelerator requires 16x16 alignment. We want the buffer
* from camera can be put in JEA directly so align the height to 16
@@ -188,14 +212,43 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
if (format == DRM_FORMAT_NV12)
height = ALIGN(height, 16);
#endif
- drv_bo_from_format(bo, stride, height, format);
+ drv_bo_from_format(bo, stride, 1, height, format);
+
+#ifdef USE_EXTRA_PADDING_FOR_YVU420
+ /*
+ * Apply extra padding for YV12 if the height does not meet round up requirement and
+ * the image is to be sampled by gpu.
+ */
+ static const uint32_t required_round_up = 4;
+ const uint32_t height_mod = height % required_round_up;
+ if ((format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID) &&
+ (bo->meta.use_flags & BO_USE_TEXTURE) && height_mod) {
+ const uint32_t height_padding = required_round_up - height_mod;
+ const uint32_t u_padding =
+ drv_size_from_format(format, bo->meta.strides[2], height_padding, 2);
+
+ bo->meta.total_size += u_padding;
+
+ /*
+ * Since we are not aligning Y, we must make sure that its padding fits
+ * inside the rest of the space allocated for the V/U planes.
+ */
+ const uint32_t y_padding =
+ drv_size_from_format(format, bo->meta.strides[0], height_padding, 0);
+ const uint32_t vu_size = drv_bo_get_plane_size(bo, 2) * 2;
+ if (y_padding > vu_size) {
+ /* Align with mali workaround to pad all 3 planes. */
+ bo->meta.total_size += y_padding + u_padding;
+ }
+ }
+#endif
}
gem_create.size = bo->meta.total_size;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create);
if (ret) {
- drv_log("DRM_IOCTL_MTK_GEM_CREATE failed (size=%" PRIu64 ")\n", gem_create.size);
+ drv_loge("DRM_IOCTL_MTK_GEM_CREATE failed (size=%" PRIu64 ")\n", gem_create.size);
return -errno;
}
@@ -213,7 +266,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
ARRAY_SIZE(modifiers));
}
-static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *mediatek_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret, prime_fd;
struct drm_mtk_gem_map_off gem_map = { 0 };
@@ -224,13 +277,13 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_MAP_OFFSET, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n");
+ drv_loge("DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n");
return MAP_FAILED;
}
prime_fd = drv_bo_get_plane_fd(bo, 0);
if (prime_fd < 0) {
- drv_log("Failed to get a prime fd\n");
+ drv_loge("Failed to get a prime fd\n");
return MAP_FAILED;
}
@@ -303,7 +356,7 @@ static int mediatek_bo_invalidate(struct bo *bo, struct mapping *mapping)
poll(&fds, 1, -1);
if (fds.revents != fds.events)
- drv_log("poll prime_fd failed\n");
+ drv_loge("poll prime_fd failed\n");
if (priv->cached_addr)
memcpy(priv->cached_addr, priv->gem_addr, bo->meta.total_size);
diff --git a/minigbm_helpers.c b/minigbm_helpers.c
index cea0b48..d1da7c4 100644
--- a/minigbm_helpers.c
+++ b/minigbm_helpers.c
@@ -17,6 +17,7 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include "gbm.h"
#include "minigbm_helpers.h"
#include "util.h"
@@ -210,7 +211,7 @@ done:
return 0;
}
-PUBLIC int gbm_get_default_device_fd(void)
+static int gbm_get_default_device_fd(void)
{
DIR *dir;
int ret, fd, dfd = -1;
@@ -312,3 +313,63 @@ PUBLIC int gbm_detect_device_info_path(unsigned int detect_flags, const char *de
close(fd);
return ret;
}
+
+static struct gbm_device *try_drm_devices(drmDevicePtr *devs, int dev_count, int type, int *out_fd)
+{
+ int i;
+
+ for (i = 0; i < dev_count; i++) {
+ drmDevicePtr dev = devs[i];
+ int fd;
+
+ if (!(dev->available_nodes & (1 << type)))
+ continue;
+
+ fd = open(dev->nodes[type], O_RDWR | O_CLOEXEC);
+ if (fd >= 0) {
+ struct gbm_device *gbm = gbm_create_device(fd);
+ if (gbm) {
+ // DRM master might be taken by accident on a primary node even
+ // if master is not needed for GBM. Drop it so that programs
+ // that actually need DRM master (e.g. Chrome) won't be blocked.
+ if (type == DRM_NODE_PRIMARY && drmIsMaster(fd))
+ drmDropMaster(fd);
+ *out_fd = fd;
+ return gbm;
+ }
+ close(fd);
+ }
+ }
+
+ return NULL;
+}
+
+PUBLIC struct gbm_device *minigbm_create_default_device(int *out_fd)
+{
+ struct gbm_device *gbm;
+ drmDevicePtr devs[64];
+ int dev_count;
+ int fd;
+
+ /* try gbm_get_default_device_fd first */
+ fd = gbm_get_default_device_fd();
+ if (fd >= 0) {
+ gbm = gbm_create_device(fd);
+ if (gbm) {
+ *out_fd = fd;
+ return gbm;
+ }
+ close(fd);
+ }
+
+ dev_count = drmGetDevices2(0, devs, sizeof(devs) / sizeof(devs[0]));
+
+ /* try render nodes and then primary nodes */
+ gbm = try_drm_devices(devs, dev_count, DRM_NODE_RENDER, out_fd);
+ if (!gbm)
+ gbm = try_drm_devices(devs, dev_count, DRM_NODE_PRIMARY, out_fd);
+
+ drmFreeDevices(devs, dev_count);
+
+ return gbm;
+}
diff --git a/minigbm_helpers.h b/minigbm_helpers.h
index 08e6283..dbbb644 100644
--- a/minigbm_helpers.h
+++ b/minigbm_helpers.h
@@ -6,6 +6,8 @@
#ifndef _MINIGBM_HELPERS_H_
#define _MINIGBM_HELPERS_H_
+#include <stdint.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -18,6 +20,8 @@ extern "C" {
#define GBM_DEV_TYPE_FLAG_BLOCKED (1u << 5) /* Unsuitable device e.g. vgem, udl, evdi. */
#define GBM_DEV_TYPE_FLAG_INTERNAL_LCD (1u << 6) /* Device is driving internal LCD. */
+struct gbm_device;
+
struct gbm_device_info {
uint32_t dev_type_flags;
int dri_node_num; /* DRI node number (0..63), for easy matching of devices. */
@@ -32,9 +36,9 @@ int gbm_detect_device_info_path(unsigned int detect_flags, const char *dev_node,
struct gbm_device_info *info);
/*
- * Select "default" device to use for graphics memory allocator.
+ * Create "default" gbm device.
*/
-int gbm_get_default_device_fd(void);
+struct gbm_device *minigbm_create_default_device(int *out_fd);
#ifdef __cplusplus
}
diff --git a/msm.c b/msm.c
index 5a2a73c..0e86d95 100644
--- a/msm.c
+++ b/msm.c
@@ -36,9 +36,9 @@
#define MSM_UBWC_TILING 1
-static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
- DRM_FORMAT_XRGB8888, DRM_FORMAT_ABGR2101010,
+static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_ABGR2101010,
DRM_FORMAT_ABGR16161616F };
static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8,
@@ -73,6 +73,8 @@ static unsigned get_pitch_alignment(struct bo *bo)
switch (bo->meta.format) {
case DRM_FORMAT_NV12:
return VENUS_STRIDE_ALIGN;
+ case DRM_FORMAT_P010:
+ return VENUS_STRIDE_ALIGN * 2;
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YVU420_ANDROID:
/* TODO other YUV formats? */
@@ -105,8 +107,8 @@ static void msm_calculate_layout(struct bo *bo)
if (bo->meta.format == DRM_FORMAT_P010)
width *= 2;
- y_stride = ALIGN(width, VENUS_STRIDE_ALIGN);
- uv_stride = ALIGN(width, VENUS_STRIDE_ALIGN);
+ y_stride = ALIGN(width, get_pitch_alignment(bo));
+ uv_stride = ALIGN(width, get_pitch_alignment(bo));
y_scanline = ALIGN(height, VENUS_SCANLINE_ALIGN * 2);
uv_scanline = ALIGN(DIV_ROUND_UP(height, 2),
VENUS_SCANLINE_ALIGN * (bo->meta.tiling ? 2 : 1));
@@ -138,7 +140,9 @@ static void msm_calculate_layout(struct bo *bo)
DRM_FORMAT_R8 of height one is used for JPEG camera output, so don't
height align that. */
if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID ||
+ bo->meta.format == DRM_FORMAT_YVU420 ||
(bo->meta.format == DRM_FORMAT_R8 && height == 1)) {
+ assert(bo->meta.tiling != MSM_UBWC_TILING);
alignh = height;
} else {
alignh = ALIGN(height, DEFAULT_ALIGNMENT);
@@ -147,7 +151,7 @@ static void msm_calculate_layout(struct bo *bo)
stride = drv_stride_from_format(bo->meta.format, alignw, 0);
/* Calculate size and assign stride, size, offset to each plane based on format */
- drv_bo_from_format(bo, stride, alignh, bo->meta.format);
+ drv_bo_from_format(bo, stride, 1, alignh, bo->meta.format);
/* For all RGB UBWC formats */
if (bo->meta.tiling == MSM_UBWC_TILING) {
@@ -204,22 +208,7 @@ static bool should_avoid_ubwc(void)
* See b/163137550
*/
if (dlsym(RTLD_DEFAULT, "waffle_display_connect")) {
- drv_log("WARNING: waffle detected, disabling UBWC\n");
- return true;
- }
-
- /* Sommelier relies on implicit modifier, which does not pass host modifier to
- * zwp_linux_buffer_params_v1_add. Graphics will be broken if UBWC is enabled.
- * Sommelier shall be fixed to mirror what arc wayland_service does, and then
- * we can re-enable UBWC here.
- *
- * Inherit the trick from crrev/c/2523246 previously used for gtest. The side
- * effect is all VM guests on msm will revert back to use linear modifier.
- *
- * See b/229147702
- */
- if (!dlsym(RTLD_DEFAULT, "cupsFilePrintf")) {
- drv_log("WARNING: virtualization detected, disabling UBWC\n");
+ drv_logi("WARNING: waffle detected, disabling UBWC\n");
return true;
}
#endif
@@ -258,7 +247,8 @@ static int msm_init(struct driver *drv)
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER |
+ BO_USE_SENSOR_DIRECT_DATA);
/*
* Android also frequently requests YV12 formats for some camera implementations
@@ -266,6 +256,8 @@ static int msm_init(struct driver *drv)
*/
drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA,
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
@@ -314,7 +306,7 @@ static int msm_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_NEW, &req);
if (ret) {
- drv_log("DRM_IOCTL_MSM_GEM_NEW failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_MSM_GEM_NEW failed with %s\n", strerror(errno));
return -errno;
}
@@ -353,22 +345,25 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_
struct combination *combo = drv_get_combination(bo->drv, format, flags);
if (!combo) {
- drv_log("invalid format = %d, flags = %" PRIx64 " combination\n", format, flags);
+ drv_loge("invalid format = %d, flags = %" PRIx64 " combination\n", format, flags);
return -EINVAL;
}
return msm_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier);
}
-static void *msm_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *msm_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
struct drm_msm_gem_info req = { 0 };
+ if (bo->meta.format_modifier)
+ return MAP_FAILED;
+
req.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_INFO, &req);
if (ret) {
- drv_log("DRM_IOCLT_MSM_GEM_INFO failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCLT_MSM_GEM_INFO failed with %s\n", strerror(errno));
return MAP_FAILED;
}
vma->length = bo->meta.total_size;
diff --git a/rockchip.c b/rockchip.c
index 6d25e3a..2dc7146 100644
--- a/rockchip.c
+++ b/rockchip.c
@@ -107,7 +107,8 @@ static int rockchip_init(struct driver *drv)
*/
drv_add_combination(drv, DRM_FORMAT_R8, &metadata,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK |
- BO_USE_LINEAR | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_LINEAR | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
+ BO_USE_GPU_DATA_BUFFER | BO_USE_SENSOR_DIRECT_DATA);
return 0;
}
@@ -135,7 +136,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
uint32_t aligned_width = w_mbs * 16;
uint32_t aligned_height = h_mbs * 16;
- drv_bo_from_format(bo, aligned_width, aligned_height, format);
+ drv_bo_from_format(bo, aligned_width, 1, aligned_height, format);
/*
* drv_bo_from_format updates total_size. Add an extra data space for rockchip video
* driver to store motion vectors.
@@ -148,7 +149,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
} else {
if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) {
errno = EINVAL;
- drv_log("no usable modifier found\n");
+ drv_loge("no usable modifier found\n");
return -errno;
}
@@ -165,15 +166,15 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
else
stride = ALIGN(stride, 64);
- drv_bo_from_format(bo, stride, height, format);
+ drv_bo_from_format(bo, stride, 1, height, format);
}
gem_create.size = bo->meta.total_size;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create);
if (ret) {
- drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%" PRIu64 ")\n",
- gem_create.size);
+ drv_loge("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%" PRIu64 ")\n",
+ gem_create.size);
return -errno;
}
@@ -191,7 +192,7 @@ static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
ARRAY_SIZE(modifiers));
}
-static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *rockchip_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
struct rockchip_private_map_data *priv;
@@ -207,7 +208,7 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3
gem_map.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n");
+ drv_loge("DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n");
return MAP_FAILED;
}
diff --git a/vc4.c b/vc4.c
index 820e4fe..d53fabf 100644
--- a/vc4.c
+++ b/vc4.c
@@ -52,7 +52,7 @@ static int vc4_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he
case DRM_FORMAT_MOD_LINEAR:
break;
case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
- drv_log("DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED not supported yet\n");
+ drv_loge("DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED not supported yet\n");
return -EINVAL;
default:
return -EINVAL;
@@ -64,13 +64,13 @@ static int vc4_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he
*/
stride = drv_stride_from_format(format, width, 0);
stride = ALIGN(stride, 64);
- drv_bo_from_format(bo, stride, height, format);
+ drv_bo_from_format(bo, stride, 1, height, format);
bo_create.size = bo->meta.total_size;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create);
if (ret) {
- drv_log("DRM_IOCTL_VC4_CREATE_BO failed (size=%zu)\n", bo->meta.total_size);
+ drv_loge("DRM_IOCTL_VC4_CREATE_BO failed (size=%zu)\n", bo->meta.total_size);
return -errno;
}
@@ -105,7 +105,7 @@ static int vc4_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t
return vc4_bo_create_for_modifier(bo, width, height, format, modifier);
}
-static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *vc4_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
struct drm_vc4_mmap_bo bo_map = { 0 };
@@ -113,7 +113,7 @@ static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m
bo_map.handle = bo->handles[0].u32;
ret = drmCommandWriteRead(bo->drv->fd, DRM_VC4_MMAP_BO, &bo_map, sizeof(bo_map));
if (ret) {
- drv_log("DRM_VC4_MMAP_BO failed\n");
+ drv_loge("DRM_VC4_MMAP_BO failed\n");
return MAP_FAILED;
}
diff --git a/virtgpu.c b/virtgpu.c
index db50b46..2f4b8db 100644
--- a/virtgpu.c
+++ b/virtgpu.c
@@ -48,7 +48,7 @@ static int virtgpu_init(struct driver *drv)
get_param.value = (uint64_t)(uintptr_t)&params[i].value;
int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param);
if (ret)
- drv_log("virtgpu backend not enabling %s\n", params[i].name);
+ drv_logi("virtgpu backend not enabling %s\n", params[i].name);
}
for (uint32_t i = 0; i < ARRAY_SIZE(virtgpu_backends); i++) {
diff --git a/virtgpu_cross_domain.c b/virtgpu_cross_domain.c
index 10930fc..45b5580 100644
--- a/virtgpu_cross_domain.c
+++ b/virtgpu_cross_domain.c
@@ -19,16 +19,16 @@
#define CAPSET_CROSS_DOMAIN 5
#define CAPSET_CROSS_FAKE 30
-static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
- DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010,
- DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010,
+static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
DRM_FORMAT_XRGB8888 };
-static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F };
-
-static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010,
- DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
+static const uint32_t texture_only_formats[] = {
+ DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010,
+ DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_ARGB2101010, DRM_FORMAT_XBGR2101010, DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_ABGR16161616F
+};
extern struct virtgpu_param params[];
@@ -53,8 +53,8 @@ static void cross_domain_release_private(struct driver *drv)
ret = drmIoctl(drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
if (ret) {
- drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n",
- priv->ring_handle, ret);
+ drv_loge("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n",
+ priv->ring_handle, ret);
}
}
@@ -78,9 +78,6 @@ static void add_combinations(struct driver *drv)
drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
&metadata, BO_USE_RENDER_MASK | BO_USE_SCANOUT);
- drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata,
- BO_USE_RENDER_MASK);
-
drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata,
BO_USE_TEXTURE_MASK);
@@ -89,15 +86,18 @@ static void add_combinations(struct driver *drv)
drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER);
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
- BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
+ BO_USE_SCANOUT | BO_USE_HW_VIDEO_ENCODER);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
- * from camera and input/output from hardware decoder/encoder.
+ * from camera, input/output from hardware decoder/encoder and sensors, and
+ * AHBs used as SSBOs/UBOs.
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_SENSOR_DIRECT_DATA |
+ BO_USE_GPU_DATA_BUFFER);
drv_modify_linear_combinations(drv);
}
@@ -109,17 +109,17 @@ static int cross_domain_submit_cmd(struct driver *drv, uint32_t *cmd, uint32_t c
struct drm_virtgpu_execbuffer exec = { 0 };
struct cross_domain_private *priv = drv->priv;
+ exec.flags = VIRTGPU_EXECBUF_RING_IDX;
exec.command = (uint64_t)&cmd[0];
exec.size = cmd_size;
if (wait) {
- exec.flags = VIRTGPU_EXECBUF_RING_IDX;
exec.bo_handles = (uint64_t)&priv->ring_handle;
exec.num_bo_handles = 1;
}
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &exec);
if (ret < 0) {
- drv_log("DRM_IOCTL_VIRTGPU_EXECBUFFER failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_EXECBUFFER failed with %s\n", strerror(errno));
return -EINVAL;
}
@@ -130,7 +130,7 @@ static int cross_domain_submit_cmd(struct driver *drv, uint32_t *cmd, uint32_t c
}
if (ret < 0) {
- drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
return ret;
}
@@ -212,6 +212,22 @@ out_unlock:
return ret;
}
+/* Fill out metadata for guest buffers, used only for CPU access: */
+void cross_domain_get_emulated_metadata(struct bo_metadata *metadata)
+{
+ uint32_t offset = 0;
+
+ for (size_t i = 0; i < metadata->num_planes; i++) {
+ metadata->strides[i] = drv_stride_from_format(metadata->format, metadata->width, i);
+ metadata->sizes[i] = drv_size_from_format(metadata->format, metadata->strides[i],
+ metadata->height, i);
+ metadata->offsets[i] = offset;
+ offset += metadata->sizes[i];
+ }
+
+ metadata->total_size = offset;
+}
+
static int cross_domain_init(struct driver *drv)
{
int ret;
@@ -264,7 +280,7 @@ static int cross_domain_init(struct driver *drv)
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
goto free_private;
}
@@ -287,7 +303,7 @@ static int cross_domain_init(struct driver *drv)
init.num_params = 2;
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_CONTEXT_INIT, &init);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_CONTEXT_INIT failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_CONTEXT_INIT failed with %s\n", strerror(errno));
goto free_private;
}
@@ -298,7 +314,7 @@ static int cross_domain_init(struct driver *drv)
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
if (ret < 0) {
- drv_log("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
+ drv_loge("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
goto free_private;
}
@@ -308,7 +324,7 @@ static int cross_domain_init(struct driver *drv)
map.handle = priv->ring_handle;
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_MAP, &map);
if (ret < 0) {
- drv_log("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
goto free_private;
}
@@ -316,7 +332,7 @@ static int cross_domain_init(struct driver *drv)
mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, drv->fd, map.offset);
if (priv->ring_addr == MAP_FAILED) {
- drv_log("mmap failed with %s\n", strerror(errno));
+ drv_loge("mmap failed with %s\n", strerror(errno));
goto free_private;
}
@@ -349,36 +365,42 @@ static int cross_domain_bo_create(struct bo *bo, uint32_t width, uint32_t height
uint32_t blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
struct drm_virtgpu_resource_create_blob drm_rc_blob = { 0 };
- ret = cross_domain_metadata_query(bo->drv, &bo->meta);
- if (ret < 0) {
- drv_log("Metadata query failed");
- return ret;
- }
-
- if (use_flags & BO_USE_SW_MASK)
+ if (use_flags & (BO_USE_SW_MASK | BO_USE_GPU_DATA_BUFFER))
blob_flags |= VIRTGPU_BLOB_FLAG_USE_MAPPABLE;
- if (params[param_cross_device].value)
- blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE;
-
- /// It may be possible to have host3d blobs and handles from guest memory at the same time.
- /// But for the immediate use cases, we will either have one or the other. For now, just
- /// prefer guest memory since adding that feature is more involved (requires --udmabuf
- /// flag to crosvm), so developers would likely test that.
- if (params[param_create_guest_handle].value) {
+ if (!(use_flags & BO_USE_HW_MASK)) {
+ cross_domain_get_emulated_metadata(&bo->meta);
drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_GUEST;
- blob_flags |= VIRTGPU_BLOB_FLAG_CREATE_GUEST_HANDLE;
- } else if (params[param_host_visible].value) {
- drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
+ } else {
+ ret = cross_domain_metadata_query(bo->drv, &bo->meta);
+ if (ret < 0) {
+ drv_loge("Metadata query failed");
+ return ret;
+ }
+
+ if (params[param_cross_device].value)
+ blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE;
+
+ /// It may be possible to have host3d blobs and handles from guest memory at the
+ /// same time. But for the immediate use cases, we will either have one or the
+ /// other. For now, just prefer guest memory since adding that feature is more
+ /// involved (requires --udmabuf flag to crosvm), so developers would likely test
+ /// that.
+ if (params[param_create_guest_handle].value) {
+ drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_GUEST;
+ blob_flags |= VIRTGPU_BLOB_FLAG_CREATE_GUEST_HANDLE;
+ } else if (params[param_host_visible].value) {
+ drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
+ }
+ drm_rc_blob.blob_id = (uint64_t)bo->meta.blob_id;
}
drm_rc_blob.size = bo->meta.total_size;
drm_rc_blob.blob_flags = blob_flags;
- drm_rc_blob.blob_id = (uint64_t)bo->meta.blob_id;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
if (ret < 0) {
- drv_log("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
+ drv_loge("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
return -errno;
}
@@ -388,7 +410,7 @@ static int cross_domain_bo_create(struct bo *bo, uint32_t width, uint32_t height
return 0;
}
-static void *cross_domain_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *cross_domain_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
struct drm_virtgpu_map gem_map = { 0 };
@@ -396,7 +418,7 @@ static void *cross_domain_bo_map(struct bo *bo, struct vma *vma, size_t plane, u
gem_map.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_MAP, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
return MAP_FAILED;
}
diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c
index 8bcfc9d..9474c40 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -6,10 +6,13 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdatomic.h>
#include <stdint.h>
+#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
+#include <unistd.h>
#include <xf86drm.h>
#include "drv_helpers.h"
@@ -22,11 +25,6 @@
#define PIPE_TEXTURE_2D 2
-#define MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS 15
-#define MESA_LLVMPIPE_MAX_TEXTURE_2D_SIZE (1 << (MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS - 1))
-#define MESA_LLVMPIPE_TILE_ORDER 6
-#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER)
-
// This comes from a combination of SwiftShader's VkPhysicalDeviceLimits::maxFramebufferWidth and
// VkPhysicalDeviceLimits::maxImageDimension2D (see https://crrev.com/c/1917130).
#define ANGLE_ON_SWIFTSHADER_MAX_TEXTURE_2D_SIZE 8192
@@ -98,7 +96,7 @@ static uint32_t translate_format(uint32_t drm_fourcc)
case DRM_FORMAT_YVU420_ANDROID:
return VIRGL_FORMAT_YV12;
default:
- drv_log("Unhandled format:%d\n", drm_fourcc);
+ drv_loge("Unhandled format:%d\n", drm_fourcc);
return 0;
}
}
@@ -352,13 +350,13 @@ static void virgl_add_combination(struct driver *drv, uint32_t drm_format,
if (params[param_3d].value) {
if ((use_flags & BO_USE_SCANOUT) &&
!virgl_supports_combination_natively(drv, drm_format, BO_USE_SCANOUT)) {
- drv_log("Strip scanout on format: %d\n", drm_format);
+ drv_logi("Strip scanout on format: %d\n", drm_format);
use_flags &= ~BO_USE_SCANOUT;
}
if (!virgl_supports_combination_natively(drv, drm_format, use_flags) &&
!virgl_supports_combination_through_emulation(drv, drm_format, use_flags)) {
- drv_log("Skipping unsupported combination format:%d\n", drm_format);
+ drv_logi("Skipping unsupported combination format:%d\n", drm_format);
return;
}
}
@@ -398,7 +396,7 @@ static inline void handle_flag(uint64_t *flag, uint64_t check_flag, uint32_t *bi
}
}
-static uint32_t compute_virgl_bind_flags(uint64_t use_flags, uint32_t format)
+static uint32_t compute_virgl_bind_flags(uint64_t use_flags)
{
/* In crosvm, VIRGL_BIND_SHARED means minigbm will allocate, not virglrenderer. */
uint32_t bind = VIRGL_BIND_SHARED;
@@ -408,6 +406,7 @@ static uint32_t compute_virgl_bind_flags(uint64_t use_flags, uint32_t format)
handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT);
handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR);
handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR);
+ handle_flag(&use_flags, BO_USE_SENSOR_DIRECT_DATA, &bind, VIRGL_BIND_LINEAR);
handle_flag(&use_flags, BO_USE_GPU_DATA_BUFFER, &bind, VIRGL_BIND_LINEAR);
handle_flag(&use_flags, BO_USE_FRONT_RENDERING, &bind, VIRGL_BIND_LINEAR);
@@ -440,7 +439,7 @@ static uint32_t compute_virgl_bind_flags(uint64_t use_flags, uint32_t format)
VIRGL_BIND_MINIGBM_HW_VIDEO_ENCODER);
if (use_flags)
- drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags);
+ drv_loge("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags);
return bind;
}
@@ -456,7 +455,7 @@ static int virgl_3d_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
if (virgl_supports_combination_natively(bo->drv, format, use_flags)) {
stride = drv_stride_from_format(format, width, 0);
- drv_bo_from_format(bo, stride, height, format);
+ drv_bo_from_format(bo, stride, 1, height, format);
} else {
assert(virgl_supports_combination_through_emulation(bo->drv, format, use_flags));
@@ -483,7 +482,7 @@ static int virgl_3d_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
res_create.target = PIPE_TEXTURE_2D;
res_create.format = translate_format(format);
- res_create.bind = compute_virgl_bind_flags(use_flags, format);
+ res_create.bind = compute_virgl_bind_flags(use_flags);
res_create.width = width;
res_create.height = height;
@@ -496,7 +495,7 @@ static int virgl_3d_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
res_create.size = ALIGN(bo->meta.total_size, PAGE_SIZE); // PAGE_SIZE = 0x1000
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno));
return ret;
}
@@ -506,7 +505,7 @@ static int virgl_3d_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui
return 0;
}
-static void *virgl_3d_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *virgl_3d_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
int ret;
struct drm_virtgpu_map gem_map = { 0 };
@@ -514,7 +513,7 @@ static void *virgl_3d_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3
gem_map.handle = bo->handles[0].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_MAP, &gem_map);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno));
return MAP_FAILED;
}
@@ -551,7 +550,7 @@ static int virgl_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
*caps_is_v2 = 0;
// Fallback to v1
@@ -560,7 +559,7 @@ static int virgl_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args);
if (ret)
- drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
}
return ret;
@@ -642,9 +641,11 @@ static int virgl_init(struct driver *drv)
virgl_add_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA,
BO_USE_SCANOUT | BO_USE_TEXTURE | BO_USE_SW_MASK |
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+ /* Android VTS sensors hal tests require BO_USE_SENSOR_DIRECT_DATA. */
drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_SENSOR_DIRECT_DATA |
+ BO_USE_GPU_DATA_BUFFER);
if (!priv->host_gbm_enabled) {
drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA,
@@ -686,7 +687,7 @@ static int virgl_bo_create_blob(struct driver *drv, struct bo *bo)
struct virgl_priv *priv = (struct virgl_priv *)drv->priv;
uint32_t blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
- if (bo->meta.use_flags & BO_USE_SW_MASK)
+ if (bo->meta.use_flags & (BO_USE_SW_MASK | BO_USE_GPU_DATA_BUFFER))
blob_flags |= VIRTGPU_BLOB_FLAG_USE_MAPPABLE;
// For now, all blob use cases are cross device. When we add wider
@@ -695,7 +696,7 @@ static int virgl_bo_create_blob(struct driver *drv, struct bo *bo)
cur_blob_id = atomic_fetch_add(&priv->next_blob_id, 1);
stride = drv_stride_from_format(bo->meta.format, bo->meta.width, 0);
- drv_bo_from_format(bo, stride, bo->meta.height, bo->meta.format);
+ drv_bo_from_format(bo, stride, 1, bo->meta.height, bo->meta.format);
bo->meta.total_size = ALIGN(bo->meta.total_size, PAGE_SIZE);
bo->meta.tiling = blob_flags;
@@ -704,8 +705,7 @@ static int virgl_bo_create_blob(struct driver *drv, struct bo *bo)
cmd[VIRGL_PIPE_RES_CREATE_WIDTH] = bo->meta.width;
cmd[VIRGL_PIPE_RES_CREATE_HEIGHT] = bo->meta.height;
cmd[VIRGL_PIPE_RES_CREATE_FORMAT] = translate_format(bo->meta.format);
- cmd[VIRGL_PIPE_RES_CREATE_BIND] =
- compute_virgl_bind_flags(bo->meta.use_flags, bo->meta.format);
+ cmd[VIRGL_PIPE_RES_CREATE_BIND] = compute_virgl_bind_flags(bo->meta.use_flags);
cmd[VIRGL_PIPE_RES_CREATE_DEPTH] = 1;
cmd[VIRGL_PIPE_RES_CREATE_BLOB_ID] = cur_blob_id;
@@ -718,7 +718,7 @@ static int virgl_bo_create_blob(struct driver *drv, struct bo *bo)
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
if (ret < 0) {
- drv_log("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
+ drv_loge("DRM_VIRTGPU_RESOURCE_CREATE_BLOB failed with %s\n", strerror(errno));
return -errno;
}
@@ -774,6 +774,21 @@ static int virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3
return virgl_2d_dumb_bo_create(bo, width, height, format, use_flags);
}
+static int virgl_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
+ uint32_t format, const uint64_t *modifiers,
+ uint32_t count)
+{
+ uint64_t use_flags = 0;
+
+ for (uint32_t i = 0; i < count; i++) {
+ if (modifiers[i] == DRM_FORMAT_MOD_LINEAR) {
+ return virgl_bo_create(bo, width, height, format, use_flags);
+ }
+ }
+
+ return -EINVAL;
+}
+
static int virgl_bo_destroy(struct bo *bo)
{
if (params[param_3d].value)
@@ -782,12 +797,42 @@ static int virgl_bo_destroy(struct bo *bo)
return drv_dumb_bo_destroy(bo);
}
-static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
+static void *virgl_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
{
if (params[param_3d].value)
- return virgl_3d_bo_map(bo, vma, plane, map_flags);
+ return virgl_3d_bo_map(bo, vma, map_flags);
else
- return drv_dumb_bo_map(bo, vma, plane, map_flags);
+ return drv_dumb_bo_map(bo, vma, map_flags);
+}
+
+static bool is_arc_screen_capture_bo(struct bo *bo)
+{
+ struct drm_prime_handle prime_handle = {};
+ int ret, fd;
+ char tmp[256];
+
+ if (bo->meta.num_planes != 1 ||
+ (bo->meta.format != DRM_FORMAT_ABGR8888 && bo->meta.format != DRM_FORMAT_ARGB8888 &&
+ bo->meta.format != DRM_FORMAT_XRGB8888 && bo->meta.format != DRM_FORMAT_XBGR8888))
+ return false;
+ prime_handle.handle = bo->handles[0].u32;
+ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_handle);
+ if (ret < 0)
+ return false;
+ snprintf(tmp, sizeof(tmp), "/proc/self/fdinfo/%d", prime_handle.fd);
+ fd = open(tmp, O_RDONLY);
+ if (fd < 0) {
+ close(prime_handle.fd);
+ return false;
+ }
+ ret = read(fd, tmp, sizeof(tmp) - 1);
+ close(prime_handle.fd);
+ close(fd);
+ if (ret < 0)
+ return false;
+ tmp[ret] = 0;
+
+ return strstr(tmp, "ARC-SCREEN-CAP");
}
static int virgl_bo_invalidate(struct bo *bo, struct mapping *mapping)
@@ -812,6 +857,15 @@ static int virgl_bo_invalidate(struct bo *bo, struct mapping *mapping)
else
host_write_flags |= BO_USE_HW_VIDEO_DECODER;
+ // TODO(b/267892346): Revert this workaround after migrating to virtgpu_cross_domain
+ // backend since it's a special arc only behavior.
+ if (!(bo->meta.use_flags & (BO_USE_ARC_SCREEN_CAP_PROBED | BO_USE_RENDERING))) {
+ bo->meta.use_flags |= BO_USE_ARC_SCREEN_CAP_PROBED;
+ if (is_arc_screen_capture_bo(bo)) {
+ bo->meta.use_flags |= BO_USE_RENDERING;
+ }
+ }
+
if ((bo->meta.use_flags & host_write_flags) == 0)
return 0;
@@ -863,8 +917,8 @@ static int virgl_bo_invalidate(struct bo *bo, struct mapping *mapping)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n",
- strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n",
+ strerror(errno));
return -errno;
}
}
@@ -875,7 +929,7 @@ static int virgl_bo_invalidate(struct bo *bo, struct mapping *mapping)
waitcmd.handle = mapping->vma->handle;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
return -errno;
}
@@ -939,8 +993,8 @@ static int virgl_bo_flush(struct bo *bo, struct mapping *mapping)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n",
- strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n",
+ strerror(errno));
return -errno;
}
}
@@ -954,7 +1008,7 @@ static int virgl_bo_flush(struct bo *bo, struct mapping *mapping)
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno));
return -errno;
}
}
@@ -968,22 +1022,31 @@ static void virgl_3d_resolve_format_and_use_flags(struct driver *drv, uint32_t f
{
*out_format = format;
*out_use_flags = use_flags;
+
+ /* resolve flexible format into explicit format */
switch (format) {
case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
/* Camera subsystem requires NV12. */
if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) {
*out_format = DRM_FORMAT_NV12;
} else {
- /* HACK: See b/28671744 */
+ /* HACK: See b/28671744 and b/264408280 */
*out_format = DRM_FORMAT_XBGR8888;
*out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER;
+ *out_use_flags |= BO_USE_LINEAR;
}
break;
case DRM_FORMAT_FLEX_YCbCr_420_888:
/* All of our host drivers prefer NV12 as their flexible media format.
* If that changes, this will need to be modified. */
*out_format = DRM_FORMAT_NV12;
- /* fallthrough */
+ break;
+ default:
+ break;
+ }
+
+ /* resolve explicit format */
+ switch (*out_format) {
case DRM_FORMAT_NV12:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ARGB8888:
@@ -992,8 +1055,8 @@ static void virgl_3d_resolve_format_and_use_flags(struct driver *drv, uint32_t f
case DRM_FORMAT_XRGB8888:
/* These are the scanout capable formats to the guest. Strip scanout use_flag if the
* host does not natively support scanout on the requested format. */
- if ((use_flags & BO_USE_SCANOUT) &&
- !virgl_supports_combination_natively(drv, format, BO_USE_SCANOUT))
+ if ((*out_use_flags & BO_USE_SCANOUT) &&
+ !virgl_supports_combination_natively(drv, *out_format, BO_USE_SCANOUT))
*out_use_flags &= ~BO_USE_SCANOUT;
break;
case DRM_FORMAT_YVU420_ANDROID:
@@ -1066,7 +1129,7 @@ static int virgl_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES],
res_info.type = VIRTGPU_RESOURCE_INFO_TYPE_EXTENDED;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO_CROS, &res_info);
if (ret) {
- drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed with %s\n", strerror(errno));
+ drv_loge("DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed with %s\n", strerror(errno));
return ret;
}
@@ -1098,6 +1161,7 @@ const struct backend virtgpu_virgl = { .name = "virtgpu_virgl",
.init = virgl_init,
.close = virgl_close,
.bo_create = virgl_bo_create,
+ .bo_create_with_modifiers = virgl_bo_create_with_modifiers,
.bo_destroy = virgl_bo_destroy,
.bo_import = drv_prime_bo_import,
.bo_map = virgl_bo_map,