gralloc: Add support for IMapper/IAllocator 4.0
* Add QtiMapper and QtiAllocator 4.0
* Implement IMapper 4.0 APIs: get, set,
getFromBufferDescriptorInfo, flushLockedBuffer,
rereadLockedBuffer, listSupportedMetadataTypes,
dumpBuffer, dumpBuffers, and getReservedRegion
Bug: 141596968
Test: VtsHalGraphicsMapperV4_0TargetTest
Change-Id: Ica42e485e426b366ffb41f30f1ea2cf395901356
diff --git a/config/display-board.mk b/config/display-board.mk
index 29f540b..dc06a64 100644
--- a/config/display-board.mk
+++ b/config/display-board.mk
@@ -17,3 +17,4 @@
SF_WCG_COMPOSITION_DATA_SPACE := 143261696
TARGET_USES_QTI_MAPPER_2_0 := true
TARGET_USES_QTI_MAPPER_EXTENSIONS_1_1 := true
+TARGET_USES_GRALLOC4 := false
\ No newline at end of file
diff --git a/config/display-product.mk b/config/display-product.mk
index 0d9fb2b..7f2f8f4 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -1,6 +1,7 @@
# Display product definitions
PRODUCT_PACKAGES += \
[email protected] \
+ [email protected] \
vendor.qti.hardware.display.allocator-service \
vendor.qti.hardware.display.composer-service \
[email protected] \
@@ -15,6 +16,7 @@
libdisplayconfig.vendor \
[email protected] \
[email protected] \
+ [email protected] \
modetest
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/gralloc/Android.mk b/gralloc/Android.mk
index b60afc0..0643fb6 100644
--- a/gralloc/Android.mk
+++ b/gralloc/Android.mk
@@ -25,8 +25,10 @@
libgralloccore \
[email protected] \
[email protected] \
- [email protected]
-LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror
+ [email protected] \
+ [email protected]
+LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror \
+ -D__QTI_DISPLAY_GRALLOC__
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_device_impl.cpp
@@ -43,8 +45,10 @@
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl \
[email protected] \
[email protected] \
- [email protected]
-LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
+ [email protected] \
+ [email protected]
+LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
+ -D__QTI_DISPLAY_GRALLOC__
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_utils.cpp gr_adreno_info.cpp gr_camera_info.cpp
include $(BUILD_SHARED_LIBRARY)
@@ -61,10 +65,13 @@
$(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl libgrallocutils libion \
+LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl libgrallocutils libion libgralloctypes \
+ libgralloc.qti libhidlbase \
[email protected] \
- [email protected]
-LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
+ [email protected] \
+ [email protected]
+LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
+ -D__QTI_DISPLAY_GRALLOC__
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_allocator.cpp gr_buf_mgr.cpp gr_ion_alloc.cpp
include $(BUILD_SHARED_LIBRARY)
@@ -90,12 +97,45 @@
[email protected] \
[email protected] \
[email protected]
-LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
+LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
+ -D__QTI_DISPLAY_GRALLOC__
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := QtiMapper.cpp QtiMapperExtensions.cpp
LOCAL_VINTF_FRAGMENTS := android.hardware.graphics.mapper-impl-qti-display.xml
include $(BUILD_SHARED_LIBRARY)
+ifneq ($(TARGET_USES_GRALLOC4),false)
+include $(CLEAR_VARS)
+LOCAL_MODULE := [email protected]
+LOCAL_SANITIZE := integer_overflow
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_SHARED_LIBRARIES := $(common_libs) \
+ libhidlbase \
+ libhidltransport \
+ libqdMetaData \
+ libgrallocutils \
+ libgralloccore \
+ libsync \
+ libgralloctypes \
+ [email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected]
+LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
+ -D__QTI_DISPLAY_GRALLOC__
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := QtiMapper4.cpp QtiMapperExtensions.cpp
+LOCAL_VINTF_FRAGMENTS := android.hardware.graphics.mapper-impl-qti-display.xml
+include $(BUILD_SHARED_LIBRARY)
+endif
+
#allocator
include $(CLEAR_VARS)
LOCAL_MODULE := vendor.qti.hardware.display.allocator-service
@@ -109,11 +149,22 @@
libqdMetaData \
libgrallocutils \
libgralloccore \
+ libgralloctypes \
+ [email protected] \
[email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected] \
[email protected] \
[email protected] \
- [email protected]
+ [email protected] \
+ [email protected] \
+ [email protected] \
+ [email protected]
LOCAL_CFLAGS := -DLOG_TAG=\"qdgralloc\" $(common_flags) $(qmaa_flags)
+ifneq ($(TARGET_USES_GRALLOC4),false)
+LOCAL_CFLAGS += -DTARGET_USES_GRALLOC4
+endif
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SRC_FILES := QtiAllocator.cpp service.cpp
diff --git a/gralloc/QtiAllocator.cpp b/gralloc/QtiAllocator.cpp
index 9b784d0..1a04237 100644
--- a/gralloc/QtiAllocator.cpp
+++ b/gralloc/QtiAllocator.cpp
@@ -32,8 +32,13 @@
#include <cutils/properties.h>
#include <log/log.h>
+#include <vendor/qti/hardware/display/mapper/3.0/IQtiMapper.h>
+#include <vendor/qti/hardware/display/mapper/4.0/IQtiMapper.h>
+
#include <vector>
+#include "QtiMapper.h"
+#include "QtiMapper4.h"
#include "gr_utils.h"
static void get_properties(gralloc::GrallocProperties *props) {
@@ -66,6 +71,8 @@
using android::hardware::hidl_handle;
using gralloc::BufferDescriptor;
+using IMapper_3_0_Error = android::hardware::graphics::mapper::V3_0::Error;
+using gralloc::Error;
QtiAllocator::QtiAllocator() {
gralloc::GrallocProperties properties;
@@ -89,9 +96,10 @@
ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
gralloc::BufferDescriptor desc;
- auto err = desc.Decode(descriptor);
+ auto err = ::vendor::qti::hardware::display::mapper::V3_0::implementation::QtiMapper::Decode(
+ descriptor, &desc);
if (err != Error::NONE) {
- hidl_cb(err, 0, hidl_vec<hidl_handle>());
+ hidl_cb(static_cast<IMapper_3_0_Error>(err), 0, hidl_vec<hidl_handle>());
return Void();
}
@@ -113,7 +121,7 @@
stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
hidl_buffers.setToExternal(buffers.data(), buffers.size());
}
- hidl_cb(err, stride, hidl_buffers);
+ hidl_cb(static_cast<IMapper_3_0_Error>(err), stride, hidl_buffers);
for (const auto &b : buffers) {
buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
@@ -122,14 +130,75 @@
return Void();
}
-// Methods from ::android::hidl::base::V1_0::IBase follow.
+} // namespace implementation
+} // namespace V3_0
+} // namespace allocator
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
-IQtiAllocator *HIDL_FETCH_IQtiAllocator(const char * /* name */) {
- return new QtiAllocator();
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace allocator {
+namespace V4_0 {
+namespace implementation {
+
+using android::hardware::hidl_handle;
+using gralloc::BufferDescriptor;
+using IMapper_4_0_Error = android::hardware::graphics::mapper::V4_0::Error;
+using gralloc::Error;
+
+QtiAllocator::QtiAllocator() {
+ gralloc::GrallocProperties properties;
+ get_properties(&properties);
+ buf_mgr_ = BufferManager::GetInstance();
+ buf_mgr_->SetGrallocDebugProperties(properties);
+}
+
+Return<void> QtiAllocator::allocate(const hidl_vec<uint8_t> &descriptor, uint32_t count,
+ allocate_cb hidl_cb) {
+ ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
+ gralloc::BufferDescriptor desc;
+
+ auto err = ::vendor::qti::hardware::display::mapper::V4_0::implementation::QtiMapper::Decode(
+ descriptor, &desc);
+ if (err != Error::NONE) {
+ hidl_cb(static_cast<IMapper_4_0_Error>(err), 0, hidl_vec<hidl_handle>());
+ return Void();
+ }
+
+ std::vector<hidl_handle> buffers;
+ buffers.reserve(count);
+ for (uint32_t i = 0; i < count; i++) {
+ buffer_handle_t buffer;
+ ALOGD_IF(DEBUG, "buffer: %p", &buffer);
+ err = buf_mgr_->AllocateBuffer(desc, &buffer);
+ if (err != Error::NONE) {
+ break;
+ }
+ buffers.emplace_back(hidl_handle(buffer));
+ }
+
+ uint32_t stride = 0;
+ hidl_vec<hidl_handle> hidl_buffers;
+ if (err == Error::NONE && buffers.size() > 0) {
+ stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
+ hidl_buffers.setToExternal(buffers.data(), buffers.size());
+ }
+ hidl_cb(static_cast<IMapper_4_0_Error>(err), stride, hidl_buffers);
+
+ for (const auto &b : buffers) {
+ buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
+ }
+
+ return Void();
}
} // namespace implementation
-} // namespace V3_0
+} // namespace V4_0
} // namespace allocator
} // namespace display
} // namespace hardware
diff --git a/gralloc/QtiAllocator.h b/gralloc/QtiAllocator.h
index 7bf1705..918c6b9 100644
--- a/gralloc/QtiAllocator.h
+++ b/gralloc/QtiAllocator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,8 +33,10 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <vendor/qti/hardware/display/allocator/3.0/IQtiAllocator.h>
+#include <vendor/qti/hardware/display/allocator/4.0/IQtiAllocator.h>
#include "gr_buf_mgr.h"
+#include "gr_utils.h"
namespace vendor {
namespace qti {
@@ -51,16 +53,16 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::hardware::graphics::allocator::V3_0::IAllocator;
-using ::android::hardware::graphics::mapper::V3_0::Error;
+using android::hardware::graphics::allocator::V3_0::IAllocator;
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::base::V1_0::IBase;
using gralloc::BufferManager;
-using ::vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator;
+using vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator;
class QtiAllocator : public IQtiAllocator {
public:
QtiAllocator();
+
// Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
Return<void> dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) override;
Return<void> allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
@@ -71,8 +73,6 @@
BufferManager *buf_mgr_ = nullptr;
};
-extern "C" IQtiAllocator *HIDL_FETCH_IQtiAllocator(const char *name);
-
} // namespace implementation
} // namespace V3_0
} // namespace allocator
@@ -81,4 +81,46 @@
} // namespace qti
} // namespace vendor
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace allocator {
+namespace V4_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using android::hardware::graphics::allocator::V4_0::IAllocator;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using gralloc::BufferManager;
+using vendor::qti::hardware::display::allocator::V4_0::IQtiAllocator;
+
+class QtiAllocator : public IQtiAllocator {
+ public:
+ QtiAllocator();
+
+ // Methods from ::android::hardware::graphics::allocator::V4_0::IAllocator follow.
+ Return<void> allocate(const hidl_vec<uint8_t> &descriptor, uint32_t count,
+ allocate_cb _hidl_cb) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ private:
+ BufferManager *buf_mgr_ = nullptr;
+};
+
+} // namespace implementation
+} // namespace V4_0
+} // namespace allocator
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
#endif // __QTIALLOCATOR_H__
diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp
index a1ac903..468a865 100644
--- a/gralloc/QtiMapper.cpp
+++ b/gralloc/QtiMapper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
namespace hardware {
namespace display {
namespace mapper {
+namespace V3_0 {
namespace implementation {
using gralloc::BufferInfo;
@@ -67,7 +68,7 @@
static_cast<uint32_t>(descriptor_info.format), descriptor_info.layerCount);
if (ValidDescriptor(descriptor_info)) {
- auto vec = gralloc::BufferDescriptor::Encode(descriptor_info);
+ auto vec = Encode(descriptor_info);
*descriptor = vec;
return Error::NONE;
} else {
@@ -105,7 +106,8 @@
return Void();
}
- auto error = buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle));
+ auto error =
+ static_cast<IMapper_3_0_Error>(buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle)));
if (error != Error::NONE) {
ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle);
native_handle_close(buffer_handle);
@@ -124,7 +126,7 @@
if (!buffer) {
return Error::BAD_BUFFER;
}
- return buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer));
+ return static_cast<IMapper_3_0_Error>(buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer)));
}
bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) {
@@ -169,7 +171,7 @@
auto hnd = PRIV_HANDLE_CONST(buffer);
- return buf_mgr_->LockBuffer(hnd, usage);
+ return static_cast<IMapper_3_0_Error>(buf_mgr_->LockBuffer(hnd, usage));
}
Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage,
@@ -215,7 +217,7 @@
Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
if (buffer != nullptr) {
- err = buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer));
+ err = static_cast<IMapper_3_0_Error>(buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer)));
}
// We don't have a release fence
hidl_cb(err, hidl_handle(nullptr));
@@ -228,14 +230,14 @@
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
- if (buf_mgr_->IsBufferImported(hnd) != Error::NONE) {
+ if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
return Error::BAD_BUFFER;
}
auto info = gralloc::BufferInfo(descriptor_info.width, descriptor_info.height,
static_cast<uint32_t>(descriptor_info.format),
static_cast<uint64_t>(descriptor_info.usage));
info.layer_count = descriptor_info.layerCount;
- err = buf_mgr_->ValidateBufferSize(hnd, info);
+ err = static_cast<IMapper_3_0_Error>(buf_mgr_->ValidateBufferSize(hnd, info));
}
return err;
}
@@ -245,7 +247,7 @@
auto hnd = static_cast<private_handle_t *>(buffer);
uint32_t num_fds = 0, num_ints = 0;
if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
- if (buf_mgr_->IsBufferImported(hnd) != Error::NONE) {
+ if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
hidl_cb(err, num_fds, num_ints);
return Void();
}
@@ -269,14 +271,14 @@
}
gralloc::BufferDescriptor desc;
- err = desc.Decode(descriptor);
+ err = static_cast<IMapper_3_0_Error>(Decode(descriptor, &desc));
if (err != Error::NONE) {
hidl_cb(err, false);
return Void();
}
buffer_handle_t buffer;
- err = buf_mgr_->AllocateBuffer(desc, &buffer, 0, true);
+ err = static_cast<IMapper_3_0_Error>(buf_mgr_->AllocateBuffer(desc, &buffer, 0, true));
if (err != Error::NONE) {
hidl_cb(err, false);
} else {
@@ -299,18 +301,19 @@
// When we are in passthrough mode, this method is used
// by hidl to obtain the SP HAL object
-IMapper_3_0 *HIDL_FETCH_IMapper(const char * /* name */) {
+extern "C" IMapper_3_0 *HIDL_FETCH_IMapper(const char * /* name */) {
ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper");
auto mapper = new QtiMapper();
return static_cast<IMapper_3_0 *>(mapper);
}
-IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) {
+extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) {
ALOGD_IF(DEBUG, "Fetching QtiMapper");
return new QtiMapper();
}
} // namespace implementation
+} // namespace V3_0
} // namespace mapper
} // namespace display
} // namespace hardware
diff --git a/gralloc/QtiMapper.h b/gralloc/QtiMapper.h
index cf17d9e..2747115 100644
--- a/gralloc/QtiMapper.h
+++ b/gralloc/QtiMapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,11 +36,14 @@
#include "QtiMapperExtensions.h"
#include "gr_buf_mgr.h"
+#include "gr_utils.h"
+
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace mapper {
+namespace V3_0 {
namespace implementation {
using ::android::sp;
@@ -66,6 +69,7 @@
using BufferDescriptorInfo_3_0 =
android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo;
using IMapperBufferDescriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+using IMapper_3_0_Error = ::android::hardware::graphics::mapper::V3_0::Error;
class QtiMapper : public IQtiMapper {
public:
@@ -91,6 +95,34 @@
Return<void> getMapperExtensions(getMapperExtensions_cb hidl_cb);
sp<mapperextensions::V1_1::IQtiMapperExtensions> extensions_ = nullptr;
+ hidl_vec<uint32_t> Encode(const IMapper_3_0::BufferDescriptorInfo &bd_info) {
+ hidl_vec<uint32_t> out;
+ out.resize(gralloc::kBufferDescriptorSize);
+ out[0] = gralloc::kMagicVersion;
+ out[1] = bd_info.width;
+ out[2] = bd_info.height;
+ out[3] = bd_info.layerCount;
+ out[4] = static_cast<uint32_t>(bd_info.format);
+ out[5] = static_cast<uint32_t>(bd_info.usage);
+ out[6] = static_cast<uint32_t>(bd_info.usage >> 32);
+ return out;
+ }
+ static gralloc::Error Decode(const hidl_vec<uint32_t> &in,
+ gralloc::BufferDescriptor *buf_descriptor) {
+ if (in.size() != gralloc::kBufferDescriptorSize || in[0] != gralloc::kMagicVersion) {
+ return gralloc::Error::BAD_DESCRIPTOR;
+ }
+ uint32_t width = static_cast<int32_t>(in[1]);
+ uint32_t height = static_cast<int32_t>(in[2]);
+ buf_descriptor->SetDimensions(width, height);
+ uint32_t layer_count = in[3];
+ buf_descriptor->SetLayerCount(layer_count);
+ uint32_t format = static_cast<int32_t>(in[4]);
+ buf_descriptor->SetColorFormat(format);
+ uint64_t usage = static_cast<uint64_t>(in[6]) << 32 | in[5];
+ buf_descriptor->SetUsage(usage);
+ return gralloc::Error::NONE;
+ }
private:
BufferManager *buf_mgr_ = nullptr;
@@ -102,10 +134,8 @@
Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence);
};
-extern "C" IMapper_3_0 *HIDL_FETCH_IMapper(const char *name);
-extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char *name);
-
} // namespace implementation
+} // namespace V3_0
} // namespace mapper
} // namespace display
} // namespace hardware
diff --git a/gralloc/QtiMapper4.cpp b/gralloc/QtiMapper4.cpp
new file mode 100644
index 0000000..83591b0
--- /dev/null
+++ b/gralloc/QtiMapper4.cpp
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#define DEBUG 0
+#include "QtiMapper4.h"
+
+#include <cutils/trace.h>
+#include <qdMetaData.h>
+#include <sync/sync.h>
+
+#include <vector>
+
+#include "gr_utils.h"
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace mapper {
+namespace V4_0 {
+namespace implementation {
+
+using gralloc::BufferInfo;
+
+using aidl::android::hardware::graphics::common::StandardMetadataType;
+QtiMapper::QtiMapper() {
+ extensions_ = new QtiMapperExtensions();
+ buf_mgr_ = BufferManager::GetInstance();
+ ALOGD_IF(DEBUG, "Created QtiMapper instance");
+}
+
+bool QtiMapper::ValidDescriptor(const BufferDescriptorInfo_4_0 &bd) {
+ if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) ||
+ bd.layerCount <= 0) {
+ return false;
+ }
+
+ return true;
+}
+
+Error QtiMapper::CreateDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info,
+ IMapperBufferDescriptor *descriptor) {
+ ALOGD_IF(DEBUG,
+ "BufferDescriptorInfo: name %s wxh: %dx%d usage: 0x%" PRIu64
+ " format: %d layer_count: %d",
+ descriptor_info.name.c_str(), descriptor_info.width, descriptor_info.height,
+ descriptor_info.usage, static_cast<uint32_t>(descriptor_info.format),
+ descriptor_info.layerCount);
+
+ if (ValidDescriptor(descriptor_info)) {
+ auto vec = Encode(descriptor_info);
+ *descriptor = vec;
+ return Error::NONE;
+ } else {
+ return Error::BAD_VALUE;
+ }
+}
+
+// Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
+Return<void> QtiMapper::createDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info,
+ createDescriptor_cb hidl_cb) {
+ IMapperBufferDescriptor descriptor;
+ auto info_4_0 = BufferDescriptorInfo_4_0{descriptor_info.name,
+ descriptor_info.width,
+ descriptor_info.height,
+ descriptor_info.layerCount,
+ static_cast<PixelFormat>(descriptor_info.format),
+ descriptor_info.usage,
+ descriptor_info.reservedSize};
+ auto err = CreateDescriptor(info_4_0, &descriptor);
+ hidl_cb(err, descriptor);
+ return Void();
+}
+
+Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) {
+ if (!raw_handle.getNativeHandle()) {
+ ALOGE("%s: Unable to import handle", __FUNCTION__);
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ native_handle_t *buffer_handle = native_handle_clone(raw_handle.getNativeHandle());
+ if (!buffer_handle) {
+ ALOGE("%s: Unable to clone handle", __FUNCTION__);
+ hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ auto error =
+ static_cast<IMapper_4_0_Error>(buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle)));
+ if (error != Error::NONE) {
+ ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle);
+ native_handle_close(buffer_handle);
+ native_handle_delete(buffer_handle);
+
+ hidl_cb(error, nullptr);
+ return Void();
+ }
+ ALOGD_IF(DEBUG, "Imported handle: %p id: %" PRIu64, buffer_handle,
+ PRIV_HANDLE_CONST(buffer_handle)->id);
+ hidl_cb(Error::NONE, buffer_handle);
+ return Void();
+}
+
+Return<Error> QtiMapper::freeBuffer(void *buffer) {
+ if (!buffer) {
+ return Error::BAD_BUFFER;
+ }
+ return static_cast<IMapper_4_0_Error>(buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer)));
+}
+
+bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) {
+ auto handle = fence_handle.getNativeHandle();
+ if (handle && handle->numFds > 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return false;
+ }
+
+ *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
+ return true;
+}
+
+void QtiMapper::WaitFenceFd(int fence_fd) {
+ if (fence_fd < 0) {
+ return;
+ }
+
+ const int timeout = 3000;
+ ATRACE_BEGIN("fence wait");
+ const int error = sync_wait(fence_fd, timeout);
+ ATRACE_END();
+ if (error < 0) {
+ ALOGE("QtiMapper: lock fence %d didn't signal in %u ms - error: %s", fence_fd, timeout,
+ strerror(errno));
+ }
+}
+
+Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence,
+ const IMapper::Rect &access_region) {
+ if (!buffer) {
+ return Error::BAD_BUFFER;
+ }
+
+ int fence_fd;
+ if (!GetFenceFd(acquire_fence, &fence_fd)) {
+ return Error::BAD_VALUE;
+ }
+
+ if (fence_fd > 0) {
+ WaitFenceFd(fence_fd);
+ }
+
+ auto hnd = PRIV_HANDLE_CONST(buffer);
+
+ if (access_region.top < 0 || access_region.left < 0 || access_region.width < 0 ||
+ access_region.height < 0 || access_region.width > hnd->width ||
+ access_region.height > hnd->height) {
+ return Error::BAD_VALUE;
+ }
+ return static_cast<IMapper_4_0_Error>(buf_mgr_->LockBuffer(hnd, usage));
+}
+
+Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
+ const hidl_handle &acquire_fence, lock_cb hidl_cb) {
+ auto err = LockBuffer(buffer, cpu_usage, acquire_fence, access_region);
+ if (err != Error::NONE) {
+ hidl_cb(err, nullptr);
+ return Void();
+ }
+
+ auto hnd = PRIV_HANDLE_CONST(buffer);
+ auto *out_data = reinterpret_cast<void *>(hnd->base);
+
+ hidl_cb(err, out_data);
+ return Void();
+}
+
+Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) {
+ auto err = Error::BAD_BUFFER;
+ if (buffer != nullptr) {
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer)));
+ }
+ // We don't have a release fence
+ hidl_cb(err, hidl_handle(nullptr));
+ return Void();
+}
+
+Return<Error> QtiMapper::validateBufferSize(void *buffer,
+ const BufferDescriptorInfo_4_0 &descriptor_info,
+ uint32_t /*stride*/) {
+ auto err = Error::BAD_BUFFER;
+ auto hnd = static_cast<private_handle_t *>(buffer);
+ if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
+ if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
+ return Error::BAD_BUFFER;
+ }
+ auto info = gralloc::BufferInfo(descriptor_info.width, descriptor_info.height,
+ static_cast<uint32_t>(descriptor_info.format),
+ static_cast<uint64_t>(descriptor_info.usage));
+ info.layer_count = descriptor_info.layerCount;
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->ValidateBufferSize(hnd, info));
+ }
+ return err;
+}
+
+Return<void> QtiMapper::getTransportSize(void *buffer, getTransportSize_cb hidl_cb) {
+ auto err = Error::BAD_BUFFER;
+ auto hnd = static_cast<private_handle_t *>(buffer);
+ uint32_t num_fds = 0, num_ints = 0;
+ if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
+ if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
+ hidl_cb(err, num_fds, num_ints);
+ return Void();
+ }
+ num_fds = 2;
+ // TODO(user): reduce to transported values;
+ num_ints = static_cast<uint32_t>(hnd->numInts);
+ err = Error::NONE;
+ }
+ ALOGD_IF(DEBUG, "GetTransportSize: num fds: %d num ints: %d err:%d", num_fds, num_ints, err);
+ hidl_cb(err, num_fds, num_ints);
+ return Void();
+}
+
+Return<void> QtiMapper::get(void *buffer, const MetadataType &metadataType, get_cb hidl_cb) {
+ auto err = Error::BAD_BUFFER;
+ hidl_vec<uint8_t> metadata;
+ if (buffer != nullptr) {
+ if (metadataType.name != GRALLOC4_STANDARD_METADATA_TYPE &&
+ metadataType.name != qtigralloc::VENDOR_QTI) {
+ hidl_cb(Error::UNSUPPORTED, metadata);
+ return Void();
+ }
+ auto hnd = static_cast<private_handle_t *>(buffer);
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->GetMetadata(hnd, metadataType.value, &metadata));
+ }
+ hidl_cb(err, metadata);
+ return Void();
+}
+
+Return<Error> QtiMapper::set(void *buffer, const MetadataType &metadataType,
+ const hidl_vec<uint8_t> &metadata) {
+ auto err = Error::BAD_BUFFER;
+ if (buffer != nullptr) {
+ auto hnd = static_cast<private_handle_t *>(buffer);
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->SetMetadata(hnd, metadataType.value, metadata));
+ }
+ return err;
+}
+
+Return<void> QtiMapper::getFromBufferDescriptorInfo(const BufferDescriptorInfo &description,
+ const MetadataType &metadataType,
+ getFromBufferDescriptorInfo_cb hidl_cb) {
+ hidl_vec<uint8_t> out;
+ auto err = Error::UNSUPPORTED;
+ switch (metadataType.value) {
+ case static_cast<int64_t>(StandardMetadataType::NAME):
+ err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeName(description.name, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::WIDTH):
+ err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeWidth(description.width, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::HEIGHT):
+ err =
+ static_cast<IMapper_4_0_Error>(android::gralloc4::encodeHeight(description.height, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::LAYER_COUNT):
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodeLayerCount(description.layerCount, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_REQUESTED):
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodePixelFormatRequested(description.format, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::USAGE):
+ err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeUsage(description.usage, &out));
+ break;
+ case static_cast<int64_t>(StandardMetadataType::COMPRESSION): {
+ int format =
+ gralloc::GetImplDefinedFormat(description.usage, static_cast<int>(description.format));
+ if (gralloc::IsUBwcEnabled(format, description.usage)) {
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodeCompression(qtigralloc::Compression_QtiUBWC, &out));
+ } else {
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodeCompression(android::gralloc4::Compression_None, &out));
+ }
+ break;
+ }
+ case static_cast<int64_t>(StandardMetadataType::PROTECTED_CONTENT): {
+ uint64_t protected_content = 0;
+ if (description.usage & GRALLOC_USAGE_PROTECTED &&
+ !(description.usage & GRALLOC_USAGE_SW_READ_MASK) &&
+ !(description.usage & GRALLOC_USAGE_SW_WRITE_MASK)) {
+ protected_content = 1;
+ }
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodeProtectedContent(protected_content, &out));
+ break;
+ }
+ case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_FOURCC):
+ case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_MODIFIER): {
+ int format =
+ gralloc::GetImplDefinedFormat(description.usage, static_cast<int>(description.format));
+ uint32_t drm_format;
+ uint64_t drm_format_modifier;
+ if (gralloc::IsUBwcEnabled(format, description.usage)) {
+ gralloc::GetDRMFormat(format, private_handle_t::PRIV_FLAGS_UBWC_ALIGNED, &drm_format,
+ &drm_format_modifier);
+ } else {
+ gralloc::GetDRMFormat(format, 0, &drm_format, &drm_format_modifier);
+ }
+ if (metadataType.value == static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_FOURCC)) {
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodePixelFormatFourCC(drm_format, &out));
+ } else {
+ err = static_cast<IMapper_4_0_Error>(
+ android::gralloc4::encodePixelFormatModifier(drm_format_modifier, &out));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ hidl_cb(err, out);
+ return Void();
+}
+Return<void> QtiMapper::flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb) {
+ auto err = Error::BAD_BUFFER;
+ if (buffer != nullptr) {
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->FlushBuffer(PRIV_HANDLE_CONST(buffer)));
+ }
+ // We don't have a release fence
+ hidl_cb(err, hidl_handle(nullptr));
+ return Void();
+}
+
+Return<Error> QtiMapper::rereadLockedBuffer(void *buffer) {
+ auto err = Error::BAD_BUFFER;
+ if (buffer != nullptr) {
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->RereadBuffer(PRIV_HANDLE_CONST(buffer)));
+ }
+ return err;
+}
+
+Return<void> QtiMapper::getReservedRegion(void *buffer, getReservedRegion_cb hidl_cb) {
+ auto hnd = static_cast<private_handle_t *>(buffer);
+ void *reserved_region = nullptr;
+ uint64_t reserved_size = 0;
+ if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
+ hidl_cb(Error::BAD_BUFFER, reserved_region, reserved_size);
+ }
+ auto err = static_cast<IMapper_4_0_Error>(
+ buf_mgr_->GetReservedRegion(hnd, &reserved_region, &reserved_size));
+
+ hidl_cb(err, reserved_region, reserved_size);
+ return Void();
+}
+Error QtiMapper::DumpBufferMetadata(const private_handle_t *buffer, BufferDump *outBufferDump) {
+ outBufferDump->metadataDump.resize(metadata_type_descriptions_.size());
+ for (int i = 0; i < static_cast<int>(metadata_type_descriptions_.size()); i++) {
+ auto type = metadata_type_descriptions_[i].metadataType;
+ hidl_vec<uint8_t> metadata;
+ if (static_cast<IMapper_4_0_Error>(buf_mgr_->GetMetadata(
+ const_cast<private_handle_t *>(buffer), type.value, &metadata)) == Error::BAD_BUFFER) {
+ // If buffer is deleted during metadata dump, return BAD_BUFFER
+ return Error::BAD_BUFFER;
+ }
+ MetadataDump metadata_dump = {type, metadata};
+ outBufferDump->metadataDump[i] = metadata_dump;
+ }
+ return Error::NONE;
+}
+Return<void> QtiMapper::dumpBuffer(void *buffer, dumpBuffer_cb hidl_cb) {
+ BufferDump buffer_dump;
+ auto hnd = PRIV_HANDLE_CONST(buffer);
+ if (buffer != nullptr) {
+ if (DumpBufferMetadata(hnd, &buffer_dump) == Error::NONE) {
+ hidl_cb(Error::NONE, buffer_dump);
+ return Void();
+ }
+ }
+ hidl_cb(Error::BAD_BUFFER, buffer_dump);
+ return Void();
+}
+Return<void> QtiMapper::dumpBuffers(dumpBuffers_cb hidl_cb) {
+ hidl_vec<BufferDump> buffers_dump;
+ std::vector<const private_handle_t *> handle_list;
+ if (static_cast<IMapper_4_0_Error>(buf_mgr_->GetAllHandles(&handle_list)) != Error::NONE) {
+ hidl_cb(Error::NO_RESOURCES, buffers_dump);
+ }
+ buffers_dump.resize(handle_list.size());
+ for (int i = 0; i < handle_list.size(); i++) {
+ BufferDump buffer_dump;
+ if (DumpBufferMetadata(handle_list[i], &buffer_dump) != Error::NONE) {
+ continue;
+ }
+ buffers_dump[i] = buffer_dump;
+ }
+ hidl_cb(Error::NONE, buffers_dump);
+ return Void();
+}
+
+Return<void> QtiMapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidl_cb) {
+ hidl_cb(Error::NONE, metadata_type_descriptions_);
+ return Void();
+}
+
+Return<void> QtiMapper::isSupported(const BufferDescriptorInfo_4_0 &descriptor_info,
+ isSupported_cb hidl_cb) {
+ IMapperBufferDescriptor descriptor;
+ auto err = CreateDescriptor(descriptor_info, &descriptor);
+ if (err != Error::NONE) {
+ hidl_cb(err, false);
+ return Void();
+ }
+
+ gralloc::BufferDescriptor desc;
+ err = static_cast<Error>(Decode(descriptor, &desc));
+ if (err != Error::NONE) {
+ hidl_cb(err, false);
+ return Void();
+ }
+
+ buffer_handle_t buffer;
+ err = static_cast<IMapper_4_0_Error>(buf_mgr_->AllocateBuffer(desc, &buffer, 0, true));
+ if (err != Error::NONE) {
+ hidl_cb(err, false);
+ } else {
+ hidl_cb(err, true);
+ }
+
+ return Void();
+}
+
+Return<void> QtiMapper::getMapperExtensions(QtiMapper::getMapperExtensions_cb hidl_cb) {
+ if (extensions_ != nullptr) {
+ hidl_cb(Error::NONE, extensions_);
+ } else {
+ hidl_cb(Error::UNSUPPORTED, extensions_);
+ }
+ return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+// When we are in passthrough mode, this method is used
+// by hidl to obtain the SP HAL object
+extern "C" IMapper *HIDL_FETCH_IMapper(const char * /* name */) {
+ ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper");
+ auto mapper = new QtiMapper();
+ return static_cast<IMapper *>(mapper);
+}
+
+extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) {
+ ALOGD_IF(DEBUG, "Fetching QtiMapper");
+ return new QtiMapper();
+}
+
+} // namespace implementation
+} // namespace V4_0
+} // namespace mapper
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
diff --git a/gralloc/QtiMapper4.h b/gralloc/QtiMapper4.h
new file mode 100644
index 0000000..c94bdef
--- /dev/null
+++ b/gralloc/QtiMapper4.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __QTIMAPPER4_H__
+#define __QTIMAPPER4_H__
+
+#include <QtiGralloc.h>
+#include <gralloctypes/Gralloc4.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <vendor/qti/hardware/display/mapper/4.0/IQtiMapper.h>
+
+#include <algorithm>
+#include <string>
+
+#include "QtiMapperExtensions.h"
+#include "gr_buf_mgr.h"
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace mapper {
+namespace V4_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+using ::android::hardware::graphics::mapper::V4_0::Error;
+using ::android::hardware::graphics::mapper::V4_0::IMapper;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using gralloc::BufferManager;
+using ::vendor::qti::hardware::display::mapper::V4_0::IQtiMapper;
+using ::vendor::qti::hardware::display::mapperextensions::V1_1::IQtiMapperExtensions;
+using ::vendor::qti::hardware::display::mapperextensions::V1_1::implementation::QtiMapperExtensions;
+
+using android::hardware::graphics::mapper::V4_0::IMapper;
+using BufferDescriptorInfo_4_0 =
+ android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
+using IMapperBufferDescriptor = android::hardware::graphics::mapper::V4_0::BufferDescriptor;
+using MetadataType = ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using MetadataTypeDescription =
+ ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
+using IMapper_4_0_Error = ::android::hardware::graphics::mapper::V4_0::Error;
+
+class QtiMapper : public IQtiMapper {
+ public:
+ QtiMapper();
+ // Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
+ Return<void> createDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info,
+ createDescriptor_cb hidl_cb) override;
+ Return<void> importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) override;
+ Return<Error> freeBuffer(void *buffer) override;
+ Return<void> lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
+ const hidl_handle &acquire_fence, lock_cb hidl_cb) override;
+ Return<void> unlock(void *buffer, unlock_cb hidl_cb) override;
+
+ // Methods from ::android::hardware::graphics::mapper::V2_1::IMapper follow.
+ Return<Error> validateBufferSize(void *buffer, const BufferDescriptorInfo_4_0 &descriptorInfo,
+ uint32_t stride) override;
+ Return<void> getTransportSize(void *buffer, getTransportSize_cb hidl_cb) override;
+
+ Return<void> isSupported(const BufferDescriptorInfo_4_0 &descriptor_info,
+ isSupported_cb hidl_cb) override;
+
+ Return<void> getMapperExtensions(getMapperExtensions_cb hidl_cb);
+ sp<mapperextensions::V1_1::IQtiMapperExtensions> extensions_ = nullptr;
+
+ // Methods from ::android::hardware::graphics::mapper::V4:0::IMapper follow.
+ Return<void> get(void *buffer, const MetadataType &metadataType, get_cb hidl_cb) override;
+ Return<Error> set(void *buffer, const MetadataType &metadataType,
+ const hidl_vec<uint8_t> &metadata) override;
+ Return<void> getFromBufferDescriptorInfo(const BufferDescriptorInfo &description,
+ const MetadataType &metadataType,
+ getFromBufferDescriptorInfo_cb hidl_cb) override;
+ Return<void> flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb);
+ Return<Error> rereadLockedBuffer(void *buffer);
+ Return<void> listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidl_cb);
+ Return<void> getReservedRegion(void *buffer, getReservedRegion_cb _hidl_cb);
+ Return<void> dumpBuffer(void *buffer, dumpBuffer_cb _hidl_cb);
+ Return<void> dumpBuffers(dumpBuffers_cb _hidl_cb);
+
+ hidl_vec<uint8_t> Encode(const BufferDescriptorInfo_4_0 &bd_info) {
+ hidl_vec<uint8_t> out;
+
+ uint64_t name_size = bd_info.name.size();
+
+ /* Name length is variable, need to store string prepended with size
+ * The rest of the packet size is constant
+ */
+ out.resize(gralloc::kBufferDescriptorSizeV4 + sizeof(name_size) + name_size);
+
+ int index = 0;
+ uint32_t magic_version = gralloc::kMagicVersion;
+ std::memcpy(&out[index], &magic_version, sizeof(magic_version));
+ index += sizeof(magic_version);
+
+ out[index] = name_size;
+ index += sizeof(name_size);
+
+ std::memcpy(&out[index], bd_info.name.c_str(), bd_info.name.size());
+ index += name_size;
+
+ std::memcpy(&out[index], &bd_info.width, sizeof(bd_info.width));
+ index += sizeof(bd_info.width);
+
+ std::memcpy(&out[index], &bd_info.height, sizeof(bd_info.height));
+ index += sizeof(bd_info.height);
+
+ std::memcpy(&out[index], &bd_info.layerCount, sizeof(bd_info.layerCount));
+ index += sizeof(bd_info.layerCount);
+
+ std::memcpy(&out[index], &bd_info.format, sizeof(bd_info.format));
+ index += sizeof(bd_info.format);
+
+ std::memcpy(&out[index], &bd_info.usage, sizeof(bd_info.usage));
+ index += sizeof(bd_info.usage);
+
+ // Cap the reserved region size at one page (4096 bytes)
+ uint64_t reserved_size = std::min(bd_info.reservedSize, (uint64_t)4096);
+ std::memcpy(&out[index], &reserved_size, sizeof(reserved_size));
+
+ return out;
+ }
+ static gralloc::Error Decode(const hidl_vec<uint8_t> &in,
+ gralloc::BufferDescriptor *buf_descriptor) {
+ // First check is to avoid dereferencing if the vector is too short
+ if (in.size() < gralloc::kBufferDescriptorSizeV4) {
+ return gralloc::Error::BAD_DESCRIPTOR;
+ }
+
+ int index = 0;
+ uint32_t magic_version;
+ std::memcpy(&magic_version, &in[index], sizeof(magic_version));
+ index += sizeof(magic_version);
+
+ uint64_t name_size = in[index];
+ index += sizeof(name_size);
+
+ // The second check validates that the size and magic version are correct
+ if (in.size() != (gralloc::kBufferDescriptorSizeV4 + name_size + sizeof(name_size)) ||
+ magic_version != gralloc::kMagicVersion) {
+ return gralloc::Error::BAD_DESCRIPTOR;
+ }
+
+ std::string name;
+
+ name.resize(name_size);
+ std::memcpy(name.data(), &in[index], name.size());
+ index += name_size;
+ buf_descriptor->SetName(name);
+
+ uint32_t width, height;
+ std::memcpy(&width, &in[index], sizeof(width));
+
+ index += sizeof(width);
+ std::memcpy(&height, &in[index], sizeof(height));
+ index += sizeof(height);
+ buf_descriptor->SetDimensions(width, height);
+
+ uint32_t layer_count;
+ std::memcpy(&layer_count, &in[index], sizeof(layer_count));
+ index += sizeof(layer_count);
+ buf_descriptor->SetLayerCount(layer_count);
+
+ uint32_t format;
+ std::memcpy(&format, &in[index], sizeof(format));
+ index += sizeof(format);
+ buf_descriptor->SetColorFormat(format);
+
+ uint64_t usage;
+ std::memcpy(&usage, &in[index], sizeof(usage));
+ index += sizeof(usage);
+ buf_descriptor->SetUsage(usage);
+
+ uint64_t reserved_size;
+ std::memcpy(&reserved_size, &in[index], sizeof(reserved_size));
+ index += sizeof(reserved_size);
+
+ buf_descriptor->SetReservedSize(reserved_size);
+ return gralloc::Error::NONE;
+ }
+
+ private:
+ BufferManager *buf_mgr_ = nullptr;
+ Error CreateDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info,
+ IMapperBufferDescriptor *descriptor);
+ bool ValidDescriptor(const IMapper::BufferDescriptorInfo &bd);
+ bool GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd);
+ void WaitFenceFd(int fence_fd);
+ Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence,
+ const IMapper::Rect &access_region);
+
+ Error DumpBufferMetadata(const private_handle_t *buffer, BufferDump *outBufferDump);
+
+ hidl_vec<MetadataTypeDescription> metadata_type_descriptions_ = {
+ // MetadataType, description, gettable, settable
+ {android::gralloc4::MetadataType_BufferId, "", true, false},
+ {android::gralloc4::MetadataType_Name, "", true, false},
+ {android::gralloc4::MetadataType_Width, "", true, false},
+ {android::gralloc4::MetadataType_Height, "", true, false},
+ {android::gralloc4::MetadataType_LayerCount, "", true, false},
+ {android::gralloc4::MetadataType_PixelFormatRequested, "", true, false},
+ {android::gralloc4::MetadataType_PixelFormatFourCC, "", true, false},
+ {android::gralloc4::MetadataType_PixelFormatModifier, "", true, false},
+ {android::gralloc4::MetadataType_Usage, "", true, false},
+ {android::gralloc4::MetadataType_AllocationSize, "", true, false},
+ {android::gralloc4::MetadataType_ProtectedContent, "", true, false},
+ {android::gralloc4::MetadataType_ChromaSiting, "", true, false},
+ {android::gralloc4::MetadataType_Compression, "", true, false},
+ {android::gralloc4::MetadataType_Interlaced, "", true, false},
+ {android::gralloc4::MetadataType_PlaneLayouts, "", true, false},
+ {android::gralloc4::MetadataType_Dataspace, "", true, true},
+ {android::gralloc4::MetadataType_BlendMode, "", true, true},
+ {android::gralloc4::MetadataType_Smpte2086, "", true, true},
+ {android::gralloc4::MetadataType_Cta861_3, "", true, true},
+ {android::gralloc4::MetadataType_Smpte2094_40, "", true, true},
+ {qtigralloc::MetadataType_VTTimestamp, "VT Timestamp", true, true},
+ {qtigralloc::MetadataType_ColorMetadata, "Color metadata", true, true},
+ {qtigralloc::MetadataType_PPParamInterlaced, "Interlaced", true, true},
+ {qtigralloc::MetadataType_VideoPerfMode, "Video perf mode", true, true},
+ {qtigralloc::MetadataType_GraphicsMetadata, "Graphics metadata", true, true},
+ {qtigralloc::MetadataType_UBWCCRStatsInfo, "UBWC stats", true, true},
+ {qtigralloc::MetadataType_RefreshRate, "Refresh rate", true, true},
+ {qtigralloc::MetadataType_MapSecureBuffer, "Secure buffer mappable", true, true},
+ {qtigralloc::MetadataType_LinearFormat, "Linear format", true, true},
+ {qtigralloc::MetadataType_SingleBufferMode, "Single buffer mode flag", true, true},
+ {qtigralloc::MetadataType_CVPMetadata, "CVP metadata", true, true},
+ {qtigralloc::MetadataType_VideoHistogramStats, "Video histogram stats", true, true},
+ {qtigralloc::MetadataType_FD, "fd from private_handle_t", true, false},
+ {qtigralloc::MetadataType_PrivateFlags, "Flags in private_handle_t", true, false},
+ };
+};
+
+} // namespace implementation
+} // namespace V4_0
+} // namespace mapper
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
+#endif // __QTIMAPPER4_H__
diff --git a/gralloc/QtiMapperExtensions.h b/gralloc/QtiMapperExtensions.h
index 1e2a4ad..5f1df06 100644
--- a/gralloc/QtiMapperExtensions.h
+++ b/gralloc/QtiMapperExtensions.h
@@ -52,7 +52,6 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::graphics::common::V1_2::PixelFormat;
-using ::android::hardware::graphics::mapper::V3_0::IMapper;
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::base::V1_0::IBase;
using gralloc::BufferManager;
diff --git a/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml b/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml
index 2eee216..b0a080e 100644
--- a/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml
+++ b/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (c) 2019, The Linux Foundation. All rights reserved.
+Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
<name>vendor.qti.hardware.display.mapper</name>
<transport arch="32+64">passthrough</transport>
<version>3.0</version>
+ <!-- <version>4.0</version> -->
<interface>
<name>IQtiMapper</name>
<instance>default</instance>
@@ -40,6 +41,7 @@
<name>android.hardware.graphics.mapper</name>
<transport arch="32+64">passthrough</transport>
<version>3.0</version>
+ <!-- <version>4.0</version> -->
<interface>
<name>IMapper</name>
<instance>default</instance>
diff --git a/gralloc/gr_buf_descriptor.h b/gralloc/gr_buf_descriptor.h
index 06b6986..32a208a 100644
--- a/gralloc/gr_buf_descriptor.h
+++ b/gralloc/gr_buf_descriptor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,47 +30,21 @@
#ifndef __GR_BUF_DESCRIPTOR_H__
#define __GR_BUF_DESCRIPTOR_H__
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <atomic>
+#include <string>
+
+#include "gr_utils.h"
namespace gralloc {
using android::hardware::hidl_vec;
-using android::hardware::graphics::mapper::V3_0::Error;
-using android::hardware::graphics::mapper::V3_0::IMapper;
-
const uint32_t kBufferDescriptorSize = 7;
+const uint32_t kBufferDescriptorSizeV4 = 42;
const uint32_t kMagicVersion = 0x76312E30; // v1.0
class BufferDescriptor {
public:
BufferDescriptor() {}
explicit BufferDescriptor(uint64_t id) : id_(id) {}
-
- static hidl_vec<uint32_t> Encode(const IMapper::BufferDescriptorInfo &bd_info) {
- hidl_vec<uint32_t> out;
- out.resize(kBufferDescriptorSize);
- out[0] = kMagicVersion;
- out[1] = bd_info.width;
- out[2] = bd_info.height;
- out[3] = bd_info.layerCount;
- out[4] = static_cast<uint32_t>(bd_info.format);
- out[5] = static_cast<uint32_t>(bd_info.usage);
- out[6] = static_cast<uint32_t>(bd_info.usage >> 32);
- return out;
- }
-
- Error Decode(const hidl_vec<uint32_t> &in) {
- if (in.size() != kBufferDescriptorSize || in[0] != kMagicVersion) {
- return Error::BAD_DESCRIPTOR;
- }
- width_ = static_cast<int32_t>(in[1]);
- height_ = static_cast<int32_t>(in[2]);
- layer_count_ = in[3];
- format_ = static_cast<int32_t>(in[4]);
- usage_ = static_cast<uint64_t>(in[6]) << 32 | in[5];
- return Error::NONE;
- }
-
void SetUsage(uint64_t usage) { usage_ |= usage; }
void SetDimensions(int w, int h) {
@@ -82,6 +56,9 @@
void SetLayerCount(uint32_t layer_count) { layer_count_ = layer_count; }
+ void SetName(std::string name) { name_ = name; }
+
+ void SetReservedSize(uint64_t reserved_size) { reserved_size_ = reserved_size; }
uint64_t GetUsage() const { return usage_; }
int GetWidth() const { return width_; }
@@ -94,13 +71,18 @@
uint64_t GetId() const { return id_; }
+ uint64_t GetReservedSize() const { return reserved_size_; }
+ std::string GetName() const { return name_; }
+
private:
+ std::string name_ = "";
int width_ = -1;
int height_ = -1;
int format_ = -1;
uint32_t layer_count_ = 1;
uint64_t usage_ = 0;
const uint64_t id_ = 0;
+ uint64_t reserved_size_ = 0;
};
}; // namespace gralloc
#endif // __GR_BUF_DESCRIPTOR_H__
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index b936539..2b670aa 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -19,25 +19,356 @@
#define DEBUG 0
+#include "gr_buf_mgr.h"
+
+#include <QtiGralloc.h>
+#include <QtiGrallocPriv.h>
+#include <gralloctypes/Gralloc4.h>
+#include <sys/mman.h>
+
#include <iomanip>
#include <sstream>
+#include <string>
#include <utility>
#include <vector>
#include "gr_adreno_info.h"
#include "gr_buf_descriptor.h"
-#include "gr_buf_mgr.h"
#include "gr_priv_handle.h"
+#include "gr_utils.h"
#include "qdMetaData.h"
#include "qd_utils.h"
namespace gralloc {
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Cta861_3;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::Rect;
+using aidl::android::hardware::graphics::common::Smpte2086;
+using aidl::android::hardware::graphics::common::StandardMetadataType;
+using aidl::android::hardware::graphics::common::XyColor;
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
descriptor.GetUsage());
}
+// duplicate from qdmetadata
+static uint64_t getMetaDataSize() {
+ return static_cast<uint64_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+static int validateAndMap(private_handle_t *handle) {
+ if (private_handle_t::validate(handle)) {
+ ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
+ return -1;
+ }
+ if (handle->fd_metadata < 0) {
+ // Silently return, metadata cannot be used
+ return -1;
+ }
+
+ if (!handle->base_metadata) {
+ auto size = getMetaDataSize();
+ void *base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
+ if (base == reinterpret_cast<void *>(MAP_FAILED)) {
+ ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
+ handle->fd_metadata, strerror(errno));
+
+ return -1;
+ }
+ handle->base_metadata = (uintptr_t)base;
+ }
+ return 0;
+}
+
+static void unmapAndReset(private_handle_t *handle) {
+ if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
+ munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
+ handle->base_metadata = 0;
+ }
+}
+
+static Error dataspaceToColorMetadata(Dataspace dataspace, ColorMetaData *color_metadata) {
+ ColorMetaData out;
+ uint32_t primaries = (uint32_t)dataspace & (uint32_t)Dataspace::STANDARD_MASK;
+ uint32_t transfer = (uint32_t)dataspace & (uint32_t)Dataspace::TRANSFER_MASK;
+ uint32_t range = (uint32_t)dataspace & (uint32_t)Dataspace::RANGE_MASK;
+
+ switch (primaries) {
+ case (uint32_t)Dataspace::STANDARD_BT709:
+ out.colorPrimaries = ColorPrimaries_BT709_5;
+ break;
+ // TODO(tbalacha): verify this is equivalent
+ case (uint32_t)Dataspace::STANDARD_BT470M:
+ out.colorPrimaries = ColorPrimaries_BT470_6M;
+ break;
+ case (uint32_t)Dataspace::STANDARD_BT601_625:
+ case (uint32_t)Dataspace::STANDARD_BT601_625_UNADJUSTED:
+ out.colorPrimaries = ColorPrimaries_BT601_6_625;
+ break;
+ case (uint32_t)Dataspace::STANDARD_BT601_525:
+ case (uint32_t)Dataspace::STANDARD_BT601_525_UNADJUSTED:
+ out.colorPrimaries = ColorPrimaries_BT601_6_525;
+ break;
+ case (uint32_t)Dataspace::STANDARD_FILM:
+ out.colorPrimaries = ColorPrimaries_GenericFilm;
+ break;
+ case (uint32_t)Dataspace::STANDARD_BT2020:
+ out.colorPrimaries = ColorPrimaries_BT2020;
+ break;
+ case (uint32_t)Dataspace::STANDARD_ADOBE_RGB:
+ out.colorPrimaries = ColorPrimaries_AdobeRGB;
+ break;
+ case (uint32_t)Dataspace::STANDARD_DCI_P3:
+ out.colorPrimaries = ColorPrimaries_DCIP3;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ /*
+ ColorPrimaries_SMPTE_240M;
+ ColorPrimaries_SMPTE_ST428;
+ ColorPrimaries_EBU3213;
+ */
+ }
+
+ switch (transfer) {
+ case (uint32_t)Dataspace::TRANSFER_SRGB:
+ out.transfer = Transfer_sRGB;
+ break;
+ case (uint32_t)Dataspace::TRANSFER_GAMMA2_2:
+ out.transfer = Transfer_Gamma2_2;
+ break;
+ case (uint32_t)Dataspace::TRANSFER_GAMMA2_8:
+ out.transfer = Transfer_Gamma2_8;
+ break;
+ case (uint32_t)Dataspace::TRANSFER_SMPTE_170M:
+ out.transfer = Transfer_SMPTE_170M;
+ break;
+ case (uint32_t)Dataspace::TRANSFER_LINEAR:
+ out.transfer = Transfer_Linear;
+ break;
+ case (uint32_t)Dataspace::TRANSFER_HLG:
+ out.transfer = Transfer_HLG;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ /*
+ Transfer_SMPTE_240M
+ Transfer_Log
+ Transfer_Log_Sqrt
+ Transfer_XvYCC
+ Transfer_BT1361
+ Transfer_sYCC
+ Transfer_BT2020_2_1
+ Transfer_BT2020_2_2
+ Transfer_SMPTE_ST2084
+ Transfer_ST_428
+ */
+ }
+
+ switch (range) {
+ case (uint32_t)Dataspace::RANGE_FULL:
+ out.range = Range_Full;
+ break;
+ case (uint32_t)Dataspace::RANGE_LIMITED:
+ out.range = Range_Limited;
+ break;
+ case (uint32_t)Dataspace::RANGE_EXTENDED:
+ out.range = Range_Extended;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ }
+
+ color_metadata->colorPrimaries = out.colorPrimaries;
+ color_metadata->transfer = out.transfer;
+ color_metadata->range = out.range;
+ return Error::NONE;
+}
+static Error colorMetadataToDataspace(ColorMetaData color_metadata, Dataspace *dataspace) {
+ Dataspace primaries, transfer, range = Dataspace::UNKNOWN;
+
+ switch (color_metadata.colorPrimaries) {
+ case ColorPrimaries_BT709_5:
+ primaries = Dataspace::STANDARD_BT709;
+ break;
+ // TODO(tbalacha): verify this is equivalent
+ case ColorPrimaries_BT470_6M:
+ primaries = Dataspace::STANDARD_BT470M;
+ break;
+ case ColorPrimaries_BT601_6_625:
+ primaries = Dataspace::STANDARD_BT601_625;
+ break;
+ case ColorPrimaries_BT601_6_525:
+ primaries = Dataspace::STANDARD_BT601_525;
+ break;
+ case ColorPrimaries_GenericFilm:
+ primaries = Dataspace::STANDARD_FILM;
+ break;
+ case ColorPrimaries_BT2020:
+ primaries = Dataspace::STANDARD_BT2020;
+ break;
+ case ColorPrimaries_AdobeRGB:
+ primaries = Dataspace::STANDARD_ADOBE_RGB;
+ break;
+ case ColorPrimaries_DCIP3:
+ primaries = Dataspace::STANDARD_DCI_P3;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ /*
+ ColorPrimaries_SMPTE_240M;
+ ColorPrimaries_SMPTE_ST428;
+ ColorPrimaries_EBU3213;
+ */
+ }
+
+ switch (color_metadata.transfer) {
+ case Transfer_sRGB:
+ transfer = Dataspace::TRANSFER_SRGB;
+ break;
+ case Transfer_Gamma2_2:
+ transfer = Dataspace::TRANSFER_GAMMA2_2;
+ break;
+ case Transfer_Gamma2_8:
+ transfer = Dataspace::TRANSFER_GAMMA2_8;
+ break;
+ case Transfer_SMPTE_170M:
+ transfer = Dataspace::TRANSFER_SMPTE_170M;
+ break;
+ case Transfer_Linear:
+ transfer = Dataspace::TRANSFER_LINEAR;
+ break;
+ case Transfer_HLG:
+ transfer = Dataspace::TRANSFER_HLG;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ /*
+ Transfer_SMPTE_240M
+ Transfer_Log
+ Transfer_Log_Sqrt
+ Transfer_XvYCC
+ Transfer_BT1361
+ Transfer_sYCC
+ Transfer_BT2020_2_1
+ Transfer_BT2020_2_2
+ Transfer_SMPTE_ST2084
+ Transfer_ST_428
+ */
+ }
+
+ switch (color_metadata.range) {
+ case Range_Full:
+ range = Dataspace::RANGE_FULL;
+ break;
+ case Range_Limited:
+ range = Dataspace::RANGE_LIMITED;
+ break;
+ case Range_Extended:
+ range = Dataspace::RANGE_EXTENDED;
+ break;
+ default:
+ return Error::UNSUPPORTED;
+ }
+
+ *dataspace = (Dataspace)((uint32_t)primaries | (uint32_t)transfer | (uint32_t)range);
+ return Error::NONE;
+}
+
+static void grallocToStandardPlaneLayoutComponentType(
+ uint32_t in, std::vector<PlaneLayoutComponent> *components) {
+ PlaneLayoutComponent comp;
+ comp.offsetInBits = 0;
+ comp.sizeInBits = 8;
+ if (in & PLANE_COMPONENT_Y) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_Y;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_Cb) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_CB;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_Cr) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_CR;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_R) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_R;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_G) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_G;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_B) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_B;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_A) {
+ comp.type = android::gralloc4::PlaneLayoutComponentType_A;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_RAW) {
+ comp.type = qtigralloc::PlaneLayoutComponentType_Raw;
+ components->push_back(comp);
+ }
+
+ if (in & PLANE_COMPONENT_META) {
+ comp.type = qtigralloc::PlaneLayoutComponentType_Meta;
+ components->push_back(comp);
+ }
+}
+
+static Error getFormatLayout(private_handle_t *handle, Rect crop_rect,
+ std::vector<PlaneLayout> *out) {
+ std::vector<PlaneLayout> plane_info;
+ int plane_count = 0;
+ BufferInfo info(handle->unaligned_width, handle->unaligned_height, handle->format, handle->usage);
+
+ gralloc::PlaneLayoutInfo plane_layout[8] = {};
+ if (gralloc::IsYuvFormat(handle->format)) {
+ gralloc::GetYUVPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
+ &plane_count, plane_layout);
+ } else if (gralloc::IsUncompressedRGBFormat(handle->format) ||
+ gralloc::IsCompressedRGBFormat(handle->format)) {
+ gralloc::GetRGBPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags,
+ &plane_count, plane_layout);
+ } else {
+ return Error::BAD_BUFFER;
+ }
+ plane_info.resize(plane_count);
+ for (int i = 0; i < plane_count; i++) {
+ std::vector<PlaneLayoutComponent> components;
+ grallocToStandardPlaneLayoutComponentType(plane_layout[i].component, &plane_info[i].components);
+ plane_info[i].horizontalSubsampling =
+ static_cast<int64_t>(pow(2, plane_layout[i].h_subsampling));
+ plane_info[i].verticalSubsampling = static_cast<int64_t>(pow(2, plane_layout[i].v_subsampling));
+ plane_info[i].offsetInBytes = static_cast<int64_t>(plane_layout[i].offset);
+ plane_info[i].sampleIncrementInBits = static_cast<int64_t>(plane_layout[i].step * 8);
+ plane_info[i].strideInBytes = static_cast<int64_t>(plane_layout[i].stride_bytes);
+ plane_info[i].totalSizeInBytes = static_cast<int64_t>(plane_layout[i].size);
+ plane_info[i].widthInSamples =
+ handle->unaligned_width * 8 / plane_info[i].sampleIncrementInBits;
+ plane_info[i].heightInSamples =
+ handle->unaligned_height * 8 / plane_info[i].sampleIncrementInBits;
+ // TODO(tbalacha): This will be removed when standard metadata type CROP_RECTANGLE is added
+ plane_info[i].crop = crop_rect;
+ }
+ *out = plane_info;
+ return Error::NONE;
+}
+
BufferManager::BufferManager() : next_id_(0) {
handles_map_.clear();
allocator_ = new Allocator();
@@ -74,7 +405,7 @@
return Error::BAD_BUFFER;
}
- unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+ unsigned int meta_size = getMetaDataSize();
if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
return Error::BAD_BUFFER;
@@ -240,6 +571,41 @@
return err;
}
+Error BufferManager::FlushBuffer(const private_handle_t *handle) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ auto status = Error::NONE;
+
+ private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+ auto buf = GetBufferFromHandleLocked(hnd);
+ if (buf == nullptr) {
+ return Error::BAD_BUFFER;
+ }
+
+ if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+ buf->ion_handle_main, CACHE_CLEAN, hnd->fd) != 0) {
+ status = Error::BAD_BUFFER;
+ }
+
+ return status;
+}
+
+Error BufferManager::RereadBuffer(const private_handle_t *handle) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ auto status = Error::NONE;
+
+ private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+ auto buf = GetBufferFromHandleLocked(hnd);
+ if (buf == nullptr) {
+ return Error::BAD_BUFFER;
+ }
+
+ if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+ buf->ion_handle_main, CACHE_INVALIDATE, hnd->fd) != 0) {
+ status = Error::BAD_BUFFER;
+ }
+
+ return status;
+}
Error BufferManager::UnlockBuffer(const private_handle_t *handle) {
std::lock_guard<std::mutex> lock(buffer_lock_);
@@ -315,7 +681,7 @@
// Allocate memory for MetaData
AllocData e_data;
- e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
+ e_data.size = getMetaDataSize();
e_data.handle = data.handle;
e_data.align = page_size;
@@ -337,7 +703,9 @@
hnd->base = 0;
hnd->base_metadata = 0;
hnd->layer_count = layer_count;
+
// set default csc as 709, but for video(yuv) its 601L
+
ColorSpace_t colorSpace = (buffer_type == BUFFER_TYPE_VIDEO) ? ITU_R_601 : ITU_R_709;
setMetaDataAndUnmap(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
@@ -346,7 +714,20 @@
setMetaDataAndUnmap(hnd, SET_GRAPHICS_METADATA, reinterpret_cast<void *>(&graphics_metadata));
}
+ auto error = validateAndMap(hnd);
+ if (error != 0) {
+ ALOGE("validateAndMap failed");
+ return Error::BAD_BUFFER;
+ }
+ auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+ descriptor.GetName().copy(metadata->name, descriptor.GetName().size() + 1);
+ metadata->name[descriptor.GetName().size()] = '\0';
+
+ metadata->reservedRegion.size = descriptor.GetReservedSize();
+ unmapAndReset(hnd);
+
*handle = hnd;
+
RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
if (DEBUG) {
@@ -379,4 +760,388 @@
}
return Error::NONE;
}
+
+// Get list of private handles in handles_map_
+Error BufferManager::GetAllHandles(std::vector<const private_handle_t *> *out_handle_list) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ if (handles_map_.empty()) {
+ return Error::NO_RESOURCES;
+ }
+ out_handle_list->reserve(handles_map_.size());
+ for (auto handle : handles_map_) {
+ out_handle_list->push_back(handle.first);
+ }
+ return Error::NONE;
+}
+Error BufferManager::GetReservedRegion(private_handle_t *handle, void **reserved_region,
+ uint64_t *reserved_region_size) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ if (!handle)
+ return Error::BAD_BUFFER;
+
+ auto buf = GetBufferFromHandleLocked(handle);
+ if (buf == nullptr)
+ return Error::BAD_BUFFER;
+
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return Error::BAD_BUFFER;
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+
+ *reserved_region = reinterpret_cast<void *>(&(metadata->reservedRegion.data));
+ *reserved_region_size = metadata->reservedRegion.size;
+
+ return Error::NONE;
+}
+
+Error BufferManager::GetMetadata(private_handle_t *handle, int64_t metadatatype_value,
+ hidl_vec<uint8_t> *out) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ if (!handle)
+ return Error::BAD_BUFFER;
+ auto buf = GetBufferFromHandleLocked(handle);
+ if (buf == nullptr)
+ return Error::BAD_BUFFER;
+
+ auto err = validateAndMap(handle);
+ if (err != 0)
+ return Error::BAD_BUFFER;
+
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+
+ Error error = Error::NONE;
+ switch (metadatatype_value) {
+ case (int64_t)StandardMetadataType::BUFFER_ID:
+ android::gralloc4::encodeBufferId((uint64_t)handle->id, out);
+ break;
+ case (int64_t)StandardMetadataType::NAME: {
+ std::string name(metadata->name);
+ android::gralloc4::encodeName(name, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::WIDTH:
+ android::gralloc4::encodeWidth((uint64_t)handle->unaligned_width, out);
+ break;
+ case (int64_t)StandardMetadataType::HEIGHT:
+ android::gralloc4::encodeHeight((uint64_t)handle->unaligned_height, out);
+ break;
+ case (int64_t)StandardMetadataType::LAYER_COUNT:
+ android::gralloc4::encodeLayerCount((uint64_t)handle->layer_count, out);
+ break;
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
+ // TODO(tbalacha): need to return IMPLEMENTATION_DEFINED,
+ // which wouldn't be known from private_handle_t
+ android::gralloc4::encodePixelFormatRequested((PixelFormat)handle->format, out);
+ break;
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: {
+ uint32_t drm_format = 0;
+ uint64_t drm_format_modifier = 0;
+ GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
+ android::gralloc4::encodePixelFormatFourCC(drm_format, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER: {
+ uint32_t drm_format = 0;
+ uint64_t drm_format_modifier = 0;
+ GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
+ android::gralloc4::encodePixelFormatModifier(drm_format_modifier, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::USAGE:
+ android::gralloc4::encodeUsage((uint64_t)handle->usage, out);
+ break;
+ case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
+ android::gralloc4::encodeAllocationSize((uint64_t)handle->size, out);
+ break;
+ case (int64_t)StandardMetadataType::PROTECTED_CONTENT: {
+ uint64_t protected_content = (handle->flags & qtigralloc::PRIV_FLAGS_SECURE_BUFFER) ? 1 : 0;
+ android::gralloc4::encodeProtectedContent(protected_content, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::CHROMA_SITING:
+ android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_Unknown, out);
+ break;
+ case (int64_t)StandardMetadataType::DATASPACE:
+ Dataspace dataspace;
+ colorMetadataToDataspace(metadata->color, &dataspace);
+ android::gralloc4::encodeDataspace(dataspace, out);
+ break;
+ case (int64_t)StandardMetadataType::INTERLACED:
+ android::gralloc4::encodeInterlaced(qtigralloc::Interlaced_Qti, out);
+ break;
+ case (int64_t)StandardMetadataType::COMPRESSION:
+ if (handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED ||
+ handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED_PI) {
+ android::gralloc4::encodeCompression(qtigralloc::Compression_QtiUBWC, out);
+ } else {
+ android::gralloc4::encodeCompression(android::gralloc4::Compression_None, out);
+ }
+ break;
+ case (int64_t)StandardMetadataType::PLANE_LAYOUTS: {
+ std::vector<PlaneLayout> plane_layouts;
+ Rect crop = {0, 0, 0, 0};
+ crop = {metadata->crop.left, metadata->crop.top, metadata->crop.right, metadata->crop.bottom};
+ getFormatLayout(handle, crop, &plane_layouts);
+ android::gralloc4::encodePlaneLayouts(plane_layouts, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::BLEND_MODE:
+ android::gralloc4::encodeBlendMode((BlendMode)metadata->blendMode, out);
+ break;
+ case (int64_t)StandardMetadataType::SMPTE2086: {
+ Smpte2086 mastering_display_values;
+ mastering_display_values.primaryRed = {
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0]) /
+ 50000.0f,
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1]) /
+ 50000.0f};
+ mastering_display_values.primaryGreen = {
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0]) /
+ 50000.0f,
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1]) /
+ 50000.0f};
+ mastering_display_values.primaryBlue = {
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0]) /
+ 50000.0f,
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1]) /
+ 50000.0f};
+ mastering_display_values.whitePoint = {
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[0]) /
+ 50000.0f,
+ static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[1]) /
+ 50000.0f};
+ mastering_display_values.maxLuminance =
+ static_cast<float>(metadata->color.masteringDisplayInfo.maxDisplayLuminance);
+ mastering_display_values.minLuminance =
+ static_cast<float>(metadata->color.masteringDisplayInfo.minDisplayLuminance) / 10000.0f;
+ android::gralloc4::encodeSmpte2086(mastering_display_values, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::CTA861_3: {
+ Cta861_3 content_light_level;
+ content_light_level.maxContentLightLevel =
+ static_cast<float>(metadata->color.contentLightLevel.maxContentLightLevel);
+ content_light_level.maxFrameAverageLightLevel =
+ static_cast<float>(metadata->color.contentLightLevel.minPicAverageLightLevel) / 10000.0f;
+ android::gralloc4::encodeCta861_3(content_light_level, out);
+ break;
+ }
+ case (int64_t)StandardMetadataType::SMPTE2094_40: {
+ std::vector<uint8_t> dynamic_metadata_payload;
+ if (metadata->color.dynamicMetaDataValid) {
+ dynamic_metadata_payload.resize(metadata->color.dynamicMetaDataLen);
+ memcpy(&dynamic_metadata_payload, &metadata->color.dynamicMetaDataPayload,
+ metadata->color.dynamicMetaDataLen);
+ android::gralloc4::encodeSmpte2094_40(dynamic_metadata_payload, out);
+ } else {
+ android::gralloc4::encodeSmpte2094_40(std::nullopt, out);
+ }
+ break;
+ }
+ case QTI_VT_TIMESTAMP:
+ android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp, metadata->vtTimeStamp,
+ out);
+ break;
+ case QTI_COLOR_METADATA:
+ qtigralloc::encodeColorMetadata(metadata->color, out);
+ break;
+ case QTI_PP_PARAM_INTERLACED:
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced,
+ metadata->interlaced, out);
+ break;
+ case QTI_VIDEO_PERF_MODE:
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode,
+ metadata->isVideoPerfMode, out);
+ break;
+ case QTI_GRAPHICS_METADATA:
+ qtigralloc::encodeGraphicsMetadata(metadata->graphics_metadata, out);
+ break;
+ case QTI_UBWC_CR_STATS_INFO:
+ qtigralloc::encodeUBWCStats(metadata->ubwcCRStats, out);
+ break;
+ case QTI_REFRESH_RATE:
+ android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate, metadata->refreshrate,
+ out);
+ break;
+ case QTI_MAP_SECURE_BUFFER:
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer,
+ metadata->mapSecureBuffer, out);
+ break;
+ case QTI_LINEAR_FORMAT:
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat, metadata->linearFormat,
+ out);
+ break;
+ case QTI_SINGLE_BUFFER_MODE:
+ android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode,
+ metadata->isSingleBufferMode, out);
+ break;
+ case QTI_CVP_METADATA:
+ qtigralloc::encodeCVPMetadata(metadata->cvpMetadata, out);
+ break;
+ case QTI_VIDEO_HISTOGRAM_STATS:
+ qtigralloc::encodeVideoHistogramMetadata(metadata->video_histogram_stats, out);
+ break;
+ case QTI_FD:
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_FD, handle->fd, out);
+ break;
+ case QTI_PRIVATE_FLAGS:
+ android::gralloc4::encodeInt32(qtigralloc::MetadataType_PrivateFlags, handle->flags, out);
+ break;
+ default:
+ error = Error::UNSUPPORTED;
+ }
+
+ return error;
+}
+
+Error BufferManager::SetMetadata(private_handle_t *handle, int64_t metadatatype_value,
+ hidl_vec<uint8_t> in) {
+ std::lock_guard<std::mutex> lock(buffer_lock_);
+ if (!handle)
+ return Error::BAD_BUFFER;
+
+ auto buf = GetBufferFromHandleLocked(handle);
+ if (buf == nullptr)
+ return Error::BAD_BUFFER;
+
+ int err = validateAndMap(handle);
+ if (err != 0)
+ return Error::BAD_BUFFER;
+
+ auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+
+ switch (metadatatype_value) {
+ // These are constant (unchanged after allocation)
+ case (int64_t)StandardMetadataType::BUFFER_ID:
+ case (int64_t)StandardMetadataType::NAME:
+ case (int64_t)StandardMetadataType::WIDTH:
+ case (int64_t)StandardMetadataType::HEIGHT:
+ case (int64_t)StandardMetadataType::LAYER_COUNT:
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
+ case (int64_t)StandardMetadataType::USAGE:
+ return Error::BAD_VALUE;
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC:
+ case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER:
+ case (int64_t)StandardMetadataType::PROTECTED_CONTENT:
+ case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
+ case (int64_t)StandardMetadataType::PLANE_LAYOUTS:
+ case (int64_t)StandardMetadataType::CHROMA_SITING:
+ case (int64_t)StandardMetadataType::INTERLACED:
+ case (int64_t)StandardMetadataType::COMPRESSION:
+ case QTI_FD:
+ case QTI_PRIVATE_FLAGS:
+ return Error::UNSUPPORTED;
+ case (int64_t)StandardMetadataType::DATASPACE:
+ Dataspace dataspace;
+ android::gralloc4::decodeDataspace(in, &dataspace);
+ dataspaceToColorMetadata(dataspace, &metadata->color);
+ break;
+ case (int64_t)StandardMetadataType::BLEND_MODE:
+ BlendMode mode;
+ android::gralloc4::decodeBlendMode(in, &mode);
+ metadata->blendMode = (int32_t)mode;
+ break;
+ case (int64_t)StandardMetadataType::SMPTE2086: {
+ std::optional<Smpte2086> mastering_display_values;
+ android::gralloc4::decodeSmpte2086(in, &mastering_display_values);
+ if (mastering_display_values != std::nullopt) {
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0] =
+ static_cast<uint32_t>(mastering_display_values->primaryRed.x * 50000.0f);
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1] =
+ static_cast<uint32_t>(mastering_display_values->primaryRed.y * 50000.0f);
+
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0] =
+ static_cast<uint32_t>(mastering_display_values->primaryGreen.x * 50000.0f);
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1] =
+ static_cast<uint32_t>(mastering_display_values->primaryGreen.y * 50000.0f);
+
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0] =
+ static_cast<uint32_t>(mastering_display_values->primaryBlue.x * 50000.0f);
+ metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1] =
+ static_cast<uint32_t>(mastering_display_values->primaryBlue.y * 50000.0f);
+
+ metadata->color.masteringDisplayInfo.primaries.whitePoint[0] =
+ static_cast<uint32_t>(mastering_display_values->whitePoint.x * 50000.0f);
+ metadata->color.masteringDisplayInfo.primaries.whitePoint[1] =
+ static_cast<uint32_t>(mastering_display_values->whitePoint.y * 50000.0f);
+
+ metadata->color.masteringDisplayInfo.maxDisplayLuminance =
+ static_cast<uint32_t>(mastering_display_values->maxLuminance);
+ metadata->color.masteringDisplayInfo.minDisplayLuminance =
+ static_cast<uint32_t>(mastering_display_values->minLuminance * 10000.0f);
+ }
+ break;
+ }
+ case (int64_t)StandardMetadataType::CTA861_3: {
+ std::optional<Cta861_3> content_light_level;
+ android::gralloc4::decodeCta861_3(in, &content_light_level);
+ if (content_light_level != std::nullopt) {
+ metadata->color.contentLightLevel.maxContentLightLevel =
+ static_cast<uint32_t>(content_light_level->maxContentLightLevel);
+ metadata->color.contentLightLevel.minPicAverageLightLevel =
+ static_cast<uint32_t>(content_light_level->maxFrameAverageLightLevel * 10000.0f);
+ }
+ break;
+ }
+ case (int64_t)StandardMetadataType::SMPTE2094_40: {
+ std::optional<std::vector<uint8_t>> dynamic_metadata_payload;
+ android::gralloc4::decodeSmpte2094_40(in, &dynamic_metadata_payload);
+ if (dynamic_metadata_payload != std::nullopt) {
+ metadata->color.dynamicMetaDataLen = dynamic_metadata_payload->size();
+ memcpy(&metadata->color.dynamicMetaDataPayload, &dynamic_metadata_payload,
+ metadata->color.dynamicMetaDataLen);
+ }
+ break;
+ }
+ case QTI_VT_TIMESTAMP:
+ android::gralloc4::decodeUint64(qtigralloc::MetadataType_VTTimestamp, in,
+ &metadata->vtTimeStamp);
+ break;
+ case QTI_COLOR_METADATA:
+ ColorMetaData color;
+ qtigralloc::decodeColorMetadata(in, &color);
+ metadata->color = color;
+ break;
+ case QTI_PP_PARAM_INTERLACED:
+ android::gralloc4::decodeInt32(qtigralloc::MetadataType_PPParamInterlaced, in,
+ &metadata->interlaced);
+ break;
+ case QTI_VIDEO_PERF_MODE:
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_VideoPerfMode, in,
+ &metadata->isVideoPerfMode);
+ break;
+ case QTI_GRAPHICS_METADATA:
+ qtigralloc::decodeGraphicsMetadata(in, &metadata->graphics_metadata);
+ break;
+ case QTI_UBWC_CR_STATS_INFO:
+ qtigralloc::decodeUBWCStats(in, &metadata->ubwcCRStats[0]);
+ break;
+ case QTI_REFRESH_RATE:
+ android::gralloc4::decodeFloat(qtigralloc::MetadataType_RefreshRate, in,
+ &metadata->refreshrate);
+ break;
+ case QTI_MAP_SECURE_BUFFER:
+ android::gralloc4::decodeInt32(qtigralloc::MetadataType_MapSecureBuffer, in,
+ &metadata->mapSecureBuffer);
+ break;
+ case QTI_LINEAR_FORMAT:
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_LinearFormat, in,
+ &metadata->linearFormat);
+ break;
+ case QTI_SINGLE_BUFFER_MODE:
+ android::gralloc4::decodeUint32(qtigralloc::MetadataType_SingleBufferMode, in,
+ &metadata->isSingleBufferMode);
+ break;
+ case QTI_CVP_METADATA:
+ qtigralloc::decodeCVPMetadata(in, &metadata->cvpMetadata);
+ break;
+ case QTI_VIDEO_HISTOGRAM_STATS:
+ qtigralloc::decodeVideoHistogramMetadata(in, &metadata->video_histogram_stats);
+ break;
+ default:
+ return Error::BAD_VALUE;
+ }
+ return Error::NONE;
+}
+
} // namespace gralloc
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
index b019c78..2295799 100644
--- a/gralloc/gr_buf_mgr.h
+++ b/gralloc/gr_buf_mgr.h
@@ -21,20 +21,20 @@
#define __GR_BUF_MGR_H__
#include <pthread.h>
+
#include <mutex>
#include <unordered_map>
#include <unordered_set>
#include <utility>
+#include <vector>
#include "gr_allocator.h"
-#include "gr_utils.h"
#include "gr_buf_descriptor.h"
+#include "gr_utils.h"
#include "gralloc_priv.h"
namespace gralloc {
-
-using android::hardware::graphics::mapper::V3_0::Error;
-
+using gralloc::Error;
class BufferManager {
public:
~BufferManager();
@@ -50,6 +50,13 @@
Error IsBufferImported(const private_handle_t *hnd);
static BufferManager *GetInstance();
void SetGrallocDebugProperties(gralloc::GrallocProperties props);
+ Error GetMetadata(private_handle_t *handle, int64_t metadatatype_value, hidl_vec<uint8_t> *out);
+ Error SetMetadata(private_handle_t *handle, int64_t metadatatype_value, hidl_vec<uint8_t> in);
+ Error GetReservedRegion(private_handle_t *handle, void **reserved_region,
+ uint64_t *reserved_region_size);
+ Error FlushBuffer(const private_handle_t *handle);
+ Error RereadBuffer(const private_handle_t *handle);
+ Error GetAllHandles(std::vector<const private_handle_t *> *out_handle_list);
private:
BufferManager();
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index 0fbf0cd..af70e4e 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -31,6 +31,8 @@
#include <media/msm_media_info.h>
#endif
+#include <drm/drm_fourcc.h>
+
#include <algorithm>
#include "gr_adreno_info.h"
@@ -1701,4 +1703,124 @@
plane_info->scanlines = height;
}
+// TODO(tbalacha): tile vs ubwc -- may need to find a diff way to differentiate
+void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format,
+ uint64_t *drm_format_modifier) {
+ bool compressed = (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) ? true : false;
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ *drm_format = DRM_FORMAT_ABGR8888;
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ *drm_format = DRM_FORMAT_ABGR1555;
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ *drm_format = DRM_FORMAT_ABGR4444;
+ break;
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ *drm_format = DRM_FORMAT_ARGB8888;
+ break;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ *drm_format = DRM_FORMAT_XBGR8888;
+ if (compressed)
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ *drm_format = DRM_FORMAT_XRGB8888;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ *drm_format = DRM_FORMAT_BGR888;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ *drm_format = DRM_FORMAT_BGR565;
+ break;
+ case HAL_PIXEL_FORMAT_BGR_565:
+ *drm_format = DRM_FORMAT_BGR565;
+ if (compressed)
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ *drm_format = DRM_FORMAT_ABGR2101010;
+ if (compressed)
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case HAL_PIXEL_FORMAT_ARGB_2101010:
+ *drm_format = DRM_FORMAT_BGRA1010102;
+ break;
+ case HAL_PIXEL_FORMAT_RGBX_1010102:
+ *drm_format = DRM_FORMAT_XBGR2101010;
+ if (compressed)
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ break;
+ case HAL_PIXEL_FORMAT_XRGB_2101010:
+ *drm_format = DRM_FORMAT_BGRX1010102;
+ break;
+ case HAL_PIXEL_FORMAT_BGRA_1010102:
+ *drm_format = DRM_FORMAT_ARGB2101010;
+ break;
+ case HAL_PIXEL_FORMAT_ABGR_2101010:
+ *drm_format = DRM_FORMAT_RGBA1010102;
+ break;
+ case HAL_PIXEL_FORMAT_BGRX_1010102:
+ *drm_format = DRM_FORMAT_XRGB2101010;
+ break;
+ case HAL_PIXEL_FORMAT_XBGR_2101010:
+ *drm_format = DRM_FORMAT_RGBX1010102;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ *drm_format = DRM_FORMAT_NV12;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ *drm_format = DRM_FORMAT_NV12;
+ if (compressed) {
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+ } else {
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE;
+ }
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ *drm_format = DRM_FORMAT_NV21;
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+ *drm_format = DRM_FORMAT_NV21;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
+ *drm_format = DRM_FORMAT_NV12;
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+ *drm_format = DRM_FORMAT_NV12;
+ if (compressed) {
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX;
+ } else {
+ *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX;
+ }
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+ *drm_format = DRM_FORMAT_NV12;
+ if (compressed) {
+ *drm_format_modifier =
+ DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
+ } else {
+ *drm_format_modifier =
+ DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
+ }
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ *drm_format = DRM_FORMAT_NV16;
+ break;
+ /*
+ TODO: No HAL_PIXEL_FORMAT equivalent?
+ case kFormatYCrCb422H2V1SemiPlanar:
+ *drm_format = DRM_FORMAT_NV61;
+ break;*/
+ case HAL_PIXEL_FORMAT_YV12:
+ *drm_format = DRM_FORMAT_YVU420;
+ break;
+ default:
+ ALOGE("Unsupported format %d", format);
+ }
+}
+
} // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index 8e6986b..40a4260 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -74,6 +74,33 @@
return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
}
+enum class Error : int32_t {
+ /**
+ * No error.
+ */
+ NONE = 0,
+ /**
+ * Invalid BufferDescriptor.
+ */
+ BAD_DESCRIPTOR = 1,
+ /**
+ * Invalid buffer handle.
+ */
+ BAD_BUFFER = 2,
+ /**
+ * Invalid HardwareBufferDescription.
+ */
+ BAD_VALUE = 3,
+ /**
+ * Resource unavailable.
+ */
+ NO_RESOURCES = 5,
+ /**
+ * Permanent failure.
+ */
+ UNSUPPORTED = 7,
+};
+
enum PlaneComponent {
/* luma */
PLANE_COMPONENT_Y = 1 << 0,
@@ -190,6 +217,9 @@
int GetBufferType(int inputFormat);
bool IsGPUFlagSupported(uint64_t usage);
bool HasAlphaComponent(int32_t format);
+
+void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format,
+ uint64_t *drm_format_modifier);
} // namespace gralloc
#endif // __GR_UTILS_H__
diff --git a/gralloc/service.cpp b/gralloc/service.cpp
index 7ea1e3a..2b890ff 100644
--- a/gralloc/service.cpp
+++ b/gralloc/service.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,21 +27,36 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <hidl/LegacySupport.h>
+
#include "QtiAllocator.h"
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
-using vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator;
-using vendor::qti::hardware::display::allocator::V3_0::implementation::QtiAllocator;
+using IQtiAllocator3 = vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator;
+using IQtiAllocator4 = vendor::qti::hardware::display::allocator::V4_0::IQtiAllocator;
int main(int, char **) {
- android::sp<IQtiAllocator> service = new QtiAllocator();
+ android::sp<IQtiAllocator3> service3 =
+ new vendor::qti::hardware::display::allocator::V3_0::implementation::QtiAllocator();
+
configureRpcThreadpool(4, true /*callerWillJoin*/);
- if (service->registerAsService() != android::OK) {
- ALOGE("Cannot register QTI Allocator service");
+ if (service3->registerAsService() != android::OK) {
+ ALOGE("Cannot register QTI Allocator 3 service");
return -EINVAL;
}
- ALOGI("Initialized qti-allocator");
+ ALOGI("Initialized qti-allocator 3");
+
+#ifdef TARGET_USES_GRALLOC4
+ android::sp<IQtiAllocator4> service4 =
+ new vendor::qti::hardware::display::allocator::V4_0::implementation::QtiAllocator();
+ if (service4->registerAsService() != android::OK) {
+ ALOGE("Cannot register QTI Allocator 4 service");
+ return -EINVAL;
+ }
+ ALOGI("Initialized qti-allocator 4");
+#endif
+
joinRpcThreadpool();
+
return 0;
}
diff --git a/gralloc/vendor.qti.hardware.display.allocator-service.xml b/gralloc/vendor.qti.hardware.display.allocator-service.xml
index eb33572..f00bda6 100644
--- a/gralloc/vendor.qti.hardware.display.allocator-service.xml
+++ b/gralloc/vendor.qti.hardware.display.allocator-service.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (c) 2019, The Linux Foundation. All rights reserved.
+Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
<name>android.hardware.graphics.allocator</name>
<transport>hwbinder</transport>
<version>3.0</version>
+ <!-- <version>4.0</version> -->
<interface>
<name>IAllocator</name>
<instance>default</instance>
@@ -40,6 +41,7 @@
<name>vendor.qti.hardware.display.allocator</name>
<transport>hwbinder</transport>
<version>3.0</version>
+ <!-- <version>4.0</version> -->
<interface>
<name>IQtiAllocator</name>
<instance>default</instance>