From a41a48a30c15951e56565cfdc7c3cee3e9b5e36e Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Mon, 18 Aug 2025 02:27:42 +0000 Subject: [PATCH 01/17] =?UTF-8?q?=E5=BC=80=E6=BA=90=E4=BB=93image=5Feffect?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0any.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- interfaces/inner_api/native/common/any.h | 943 +++++++++++++++++- .../inner_api/native/common/type_cast_ext.h | 67 ++ 2 files changed, 1005 insertions(+), 5 deletions(-) create mode 100644 interfaces/inner_api/native/common/type_cast_ext.h diff --git a/interfaces/inner_api/native/common/any.h b/interfaces/inner_api/native/common/any.h index 3e98166..80e8cbd 100644 --- a/interfaces/inner_api/native/common/any.h +++ b/interfaces/inner_api/native/common/any.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * 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 @@ -13,9 +13,942 @@ * limitations under the License. */ -#ifndef IMAGE_EFFECT_ANY_H -#define IMAGE_EFFECT_ANY_H +#ifndef HISTREAMER_PLUGIN_COMMON_ANY_H +#define HISTREAMER_PLUGIN_COMMON_ANY_H -#include "meta/any.h" +#ifndef HST_ANY_WITH_RTTI +#ifndef HST_ANY_WITH_NO_RTTI +#define HST_ANY_WITH_NO_RTTI +#endif +#else +#ifdef HST_ANY_WITH_NO_RTTI +#undef HST_ANY_WITH_NO_RTTI +#endif +#endif -#endif // IMAGE_EFFECT_ANY_H +#ifndef MEDIA_NO_OHOS +#ifndef MEDIA_OHOS +#define MEDIA_OHOS +#endif +#else +#ifdef MEDIA_OHOS +#undef MEDIA_OHOS +#endif +#endif + +#if defined(__clang__) || defined(__GNUC__) +#define CPP_STANDARD __cplusplus +#elif defined(_MSC_VER) +#define CPP_STANDARD _MSVC_LANG +#endif + +#if CPP_STANDARD >= 201103L + +#include +#include +#include "type_cast_ext.h" +#include "securec.h" +#include +#include "message_parcel.h" + +namespace { +#if CPP_STANDARD < 201402L +template +using decay_t = typename std::decay::type; + +template +using enable_if_t = typename std::enable_if::type; + +template +using conditional_t = typename std::conditional::type; + +template +using remove_cv_t = typename std::remove_cv::type; + +template +using remove_reference_t = typename std::remove_reference::type; +#else +using std::decay_t; +using std::enable_if_t; +using std::conditional_t; +using std::remove_cv_t; +using std::remove_reference_t; +#endif + +constexpr size_t STACK_STORAGE_SIZE = 2 * sizeof(void*); // NOLINT: global var + +template +struct IsTrivialStackStorable { + static constexpr bool value = + alignof(T) <= alignof(max_align_t) && std::is_trivially_copyable::value && sizeof(T) <= STACK_STORAGE_SIZE; +}; + +template +struct IsStackStorable { + static constexpr bool value = alignof(T) <= alignof(max_align_t) && std::is_nothrow_move_constructible::value && + sizeof(T) <= STACK_STORAGE_SIZE; +}; + +template +struct IsValidCast { + static constexpr bool value = std::is_reference::value || std::is_copy_constructible::value; +}; +} // namespace +namespace OHOS { +namespace Media { + +enum struct AnyValueType : int32_t { + INVALID_TYPE = 1, + BOOL, + INT8_T, + UINT8_T, + INT32_T, + UINT32_T, + INT64_T, + UINT64_T, + FLOAT, + DOUBLE, + VECTOR_UINT8, + VECTOR_UINT32, + STRING, + VECTOR_INT32, +}; +/** + * @brief BadAnyCast exception, which is thrown when error occurs in AnyCast + * + * @since 1.0 + * @version 1.0 + */ +class BadAnyCast : public std::bad_cast { +public: + const char* what() const noexcept override + { + return "bad any cast"; + } +}; +class Any; +template +inline typename std::enable_if::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel& parcel); +template +inline typename std::enable_if::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel& parcel) +{ + (void)value; + (void)parcel; + // current only support enum from parcel + return false; +} +template +inline typename std::enable_if::value, bool>::type WriteValueToParcel(const T &value, + MessageParcel &parcel) +{ + parcel.WriteInt32(static_cast(value)); + return true; +} +template +inline typename std::enable_if::value, bool>::type WriteValueToParcel(const T &value, + MessageParcel &parcel) +{ + (void)value; + (void)parcel; + // current only support write enum to parcel + return false; +} +template +inline typename std::enable_if::value, bool>::type WriteValueToParcelInt64(const T &value, + MessageParcel &parcel) +{ + parcel.WriteInt64(static_cast(value)); + return true; +} +template +inline typename std::enable_if::value, bool>::type WriteValueToParcelInt64(const T &value, + MessageParcel &parcel) +{ + (void)value; + (void)parcel; + // current only support write enum to parcel + return false; +} +/** + * @brief This class describes a type-safe container for arbitrary type values which are copy constructible. + * + * @since 1.0 + * @version 1.0 + */ +class Any final { +public: + constexpr Any() noexcept + { + } + + __attribute__((no_sanitize("cfi"))) Any(const Any &other) : functionTable_(other.functionTable_) + { + if (other.HasValue()) { + functionTable_->copy(storage_, other.storage_); + } + } + + __attribute__((no_sanitize("cfi"))) Any(Any &&other) noexcept : functionTable_(other.functionTable_) + { + if (other.HasValue()) { + functionTable_->move(storage_, other.storage_); + other.functionTable_ = nullptr; + } + } + + /** + * constructor from right reference value with type of ValueType. + * + * @tparam Type ValueType is not the same as Any itself. The decay type of ValueType must be copy constructible. + * @param value content + */ + template , Any>::value && + std::is_copy_constructible>::value, + bool> = true> + Any(ValueType&& value) // NOLINT: explicit + { + DoEmplace>(std::forward(value)); + } + + Any& operator=(const Any& other) + { + *this = Any(other); + return *this; + } + + Any& operator=(Any&& other) noexcept + { + Reset(); + MoveFrom(std::forward(other)); + return *this; + } + + /** + * Assigns contents to Any. + * + * @tparam ValueType Type ValueType is not the same as Any itself. The decay type of ValueType must be copy + * constructible. + * @param value content + * @return + */ + template , Any>::value && + std::is_copy_constructible>::value, + bool> = true> + Any& operator=(ValueType&& value) + { + *this = Any(std::forward(value)); + return *this; + } + + /** + * Get TypeName From function info. + * @return Name of Type T + */ + template + static constexpr std::string_view GetTypeName() noexcept + { + const char* functionInfo = __PRETTY_FUNCTION__ ; + return GetTypeNameFromFunctionInfo(functionInfo); + } + + template + static bool IsSameTypeWith(const Any& other) noexcept + { +#ifndef HST_ANY_WITH_NO_RTTI + return other.SameTypeWith(typeid(T)); +#else + return other.SameTypeWith(Any::GetTypeName()); +#endif + } + + ~Any() + { + Reset(); + } + + /** + * Emplace one content with type of ValueType into object. The content is constructed by args. + * + * @tparam ValueType The decay type of ValueType must be constructible from args and copy constructible. + * @tparam Args args type + * @param args args + * @return content with type of decay ValueType + */ + template , Args...>::value && + std::is_copy_constructible>::value, + bool> = true> + decay_t& Emplace(Args&&... args) + { + Reset(); + return DoEmplace>(std::forward(args)...); + } + + /** + * Emplace one content with type of ValueType into object. The content is constructed by il and args. + * + * @tparam ValueType type of conetent. The decay type of ValueType must be constructible from il and args and copy + * constructible + * @tparam U type of initializer list. + * @tparam Args type of other args + * @param il initializer list + * @param args args + * @return content with type of decay ValueType + */ + template , std::initializer_list&, Args...>::value && + std::is_copy_constructible>::value, + bool> = true> + decay_t& Emplace(std::initializer_list il, Args&&... args) + { + Reset(); + return DoEmplace>(il, std::forward(args)...); + } + + /** + * Destroy the inner content if exists. + */ + void __attribute__((no_sanitize("cfi"))) Reset() noexcept + { + if (HasValue()) { + functionTable_->destroy(storage_); + storage_.trivialStack_.fill(0); + } + functionTable_ = nullptr; + } + + /** + * swap contents of two any objects + * + * @param other object to swap with + */ + void Swap(Any& other) noexcept + { + Any tmp(std::move(*this)); + *this = std::move(other); + other = std::move(tmp); + } + + /** + * Checks whether the object has one content. + * + * @return true if object has one content, otherwise false. + */ + bool HasValue() const noexcept + { + return IsFunctionTableValid(); + } + +#ifndef HST_ANY_WITH_NO_RTTI + /** + * Get tye type_info of object + * + * @return type info of object + */ + const std::type_info& Type() const noexcept + { + if (!HasValue()) { + return typeid(void); + } + return functionTable_->type(); + } +#else + std::string_view __attribute__((no_sanitize("cfi"))) TypeName() const noexcept + { + if (!HasValue()) { + return "empty"; // no value + } + return functionTable_->type_name(); + } + bool __attribute__((no_sanitize("cfi"))) ToParcel(MessageParcel &parcel) const noexcept + { + if (!HasValue()) { + return false; // no value + } + return functionTable_->toParcel(this, parcel); + } + bool __attribute__((no_sanitize("cfi"))) FromParcel(MessageParcel &parcel) const noexcept + { + return functionTable_->fromParcel(const_cast(this), parcel); + } +#endif + +#ifndef HST_ANY_WITH_NO_RTTI + bool SameTypeWith(const std::type_info& otherInfo) const noexcept + { + if (functionTable_ == nullptr) { + return false; + } + return IsSameType(functionTable_->type(), otherInfo); + } +#else + bool __attribute__((no_sanitize("cfi"))) SameTypeWith(std::string_view otherTypeName) const noexcept + { + if (functionTable_ == nullptr) { + return false; + } + return IsSameType(functionTable_->type_name(), otherTypeName); + } +#endif + + bool __attribute__((no_sanitize("cfi"))) SameTypeWith(const Any &other) const noexcept + { +#ifndef HST_ANY_WITH_NO_RTTI + return IsSameType(functionTable_->type(), other.Type()); +#else + return IsSameType(functionTable_->type_name(), other.TypeName()); +#endif + } + +private: + template + friend const T* AnyCast(const Any* operand) noexcept; + template + friend T* AnyCast(Any* operand) noexcept; + template + friend bool AnyCast(const Any* operand, T& value) noexcept; + + union Storage { + using Stack = std::aligned_storage::value>::type; + using Heap = void*; + + std::array trivialStack_; + Stack nonTrivialStack_; + Heap heap_; + }; + + struct FunctionTable { +#ifndef HST_ANY_WITH_NO_RTTI + const std::type_info& (*type)() noexcept; +#else + std::string_view (*type_name)() noexcept; + bool (*toParcel)(const Any *operand, MessageParcel& parcel) noexcept; + bool (*fromParcel)(Any *operand, MessageParcel& parcel) noexcept; +#endif + void (*destroy)(Storage&) noexcept; + void (*copy)(Storage&, const Storage&) noexcept; + void (*move)(Storage&, Storage&) noexcept; + void* (*getPtr)(Storage&) noexcept; + const void* (*getConstPtr)(const Storage&) noexcept; + }; + static bool BaseTypesToParcel(const Any *operand, MessageParcel& parcel) noexcept; + // returnValue : 0 -- success; 1 -- retry enum; 2 -- failed no retry + static int BaseTypesFromParcel(Any *operand, MessageParcel& parcel) noexcept; + + static std::string_view GetTypeNameFromFunctionInfo(const char* functionInfo) noexcept; + + template + struct TrivialStackFunctionTable { +#ifndef HST_ANY_WITH_NO_RTTI + static const std::type_info& Type() noexcept + { + return typeid(T); + } +#else + static std::string_view TypeName() noexcept + { + return GetTypeName(); + } + // Only support parcel enum value to int32_t except base types + static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept + { + if (BaseTypesToParcel(operand, parcel)) { + return true; + } + if (sizeof(T) > sizeof(int64_t)) { // Only support enum + return false; + } + if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum + T value; + if (AnyCast(operand, value)) { + WriteValueToParcelInt64(value, parcel); + return true; + } + return false; + } + T value; + if (AnyCast(operand, value)) { + WriteValueToParcel(value, parcel); + return true; + } + return false; + } + + static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept + { + int ret = BaseTypesFromParcel(operand, parcel); + if (ret == 0) { + return true; + } + MakeAnyFromParcel(*operand, parcel); + return true; + } +#endif + + static void Destroy(Storage& storage) noexcept + { + reinterpret_cast(storage.trivialStack_.data())->~T(); + } + + static void Copy(Storage& dest, const Storage& source) noexcept + { + // memcpy_s will always success in this function + (void)memcpy_s(GetPtr(dest), sizeof(Storage), GetConstPtr(source), sizeof(Storage)); + } + + static void Move(Storage& dest, Storage& source) noexcept + { + Copy(dest, source); + source.trivialStack_.fill(0); + } + + static const void* GetConstPtr(const Storage& storage) noexcept + { + return reinterpret_cast(storage.trivialStack_.data()); + } + + static void* GetPtr(Storage& storage) noexcept + { + return reinterpret_cast(storage.trivialStack_.data()); + } + }; + + template + struct StackFunctionTable { +#ifndef HST_ANY_WITH_NO_RTTI + static const std::type_info& Type() noexcept + { + return typeid(T); + } +#else + static std::string_view TypeName() noexcept + { + return GetTypeName(); + } + // Only support parcel enum value to int32_t except base types + static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept + { + if (BaseTypesToParcel(operand, parcel)) { + return true; + } + if (sizeof(T) > sizeof(int64_t)) { // Only support enum + return false; + } + if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum + T value; + if (AnyCast(operand, value)) { + WriteValueToParcelInt64(value, parcel); + return true; + } + return false; + } + T value; + if (AnyCast(operand, value)) { + WriteValueToParcel(value, parcel); + return true; + } + return false; + } + + static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept + { + int ret = BaseTypesFromParcel(operand, parcel); + if (ret == 0) { + return true; + } + MakeAnyFromParcel(*operand, parcel); + return true; + } +#endif + + static void Destroy(Storage& storage) noexcept + { + reinterpret_cast(GetPtr(storage))->~T(); // NOLINT: cast + } + + static void Copy(Storage& dest, const Storage& source) noexcept + { + // NOLINTNEXTLINE: reinterpret_cast + new (reinterpret_cast(GetPtr(dest))) T(*reinterpret_cast(GetConstPtr(source))); + } + + static void Move(Storage& dest, Storage& source) noexcept + { + // NOLINTNEXTLINE: reinterpret_cast + new (reinterpret_cast(GetPtr(dest))) T(std::move(*reinterpret_cast(GetPtr(source)))); + Destroy(source); + } + + static const void* GetConstPtr(const Storage& storage) noexcept + { + return reinterpret_cast(&storage.nonTrivialStack_); + } + + static void* GetPtr(Storage& storage) noexcept + { + return reinterpret_cast(&storage.nonTrivialStack_); + } + }; + + template + struct HeapFunctionTable { +#ifndef HST_ANY_WITH_NO_RTTI + static const std::type_info& Type() noexcept + { + return typeid(T); + } +#else + static std::string_view TypeName() noexcept + { + return GetTypeName(); + } + // Only support parcel enum value to int32_t except base types + static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept + { + if (BaseTypesToParcel(operand, parcel)) { + return true; + } + if (sizeof(T) > sizeof(int64_t)) { // Only support enum + return false; + } + if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum + T value; + if (AnyCast(operand, value)) { + WriteValueToParcelInt64(value, parcel); + return true; + } + return false; + } + T value; + if (AnyCast(operand, value)) { + WriteValueToParcel(value, parcel); + return true; + } + return false; + } + + static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept + { + int ret = BaseTypesFromParcel(operand, parcel); + if (ret == 0) { + return true; + } + MakeAnyFromParcel(*operand, parcel); + return true; + } +#endif + + static void Destroy(Storage& storage) noexcept + { + delete reinterpret_cast(storage.heap_); // NOLINT: cast + storage.heap_ = nullptr; + } + static void Copy(Storage& dest, const Storage& source) noexcept + { + dest.heap_ = new T(*reinterpret_cast(source.heap_)); // NOLINT: cast + } + static void Move(Storage& dest, Storage& source) noexcept + { + dest.heap_ = source.heap_; + source.heap_ = nullptr; + } + static const void* GetConstPtr(const Storage& storage) noexcept + { + return storage.heap_; + } + static void* GetPtr(Storage& storage) noexcept + { + return storage.heap_; + } + }; + + template + static FunctionTable* GetFunctionTable() + { + using DecayedValueType = decay_t; + using DetailFunctionTable = + conditional_t::value, + TrivialStackFunctionTable, + conditional_t::value, + StackFunctionTable, HeapFunctionTable>>; + static FunctionTable table = { +#ifndef HST_ANY_WITH_NO_RTTI + .type = DetailFunctionTable::Type, +#else + .type_name = DetailFunctionTable::TypeName, + .toParcel = DetailFunctionTable::ToParcel, + .fromParcel = DetailFunctionTable::FromParcel, +#endif + .destroy = DetailFunctionTable::Destroy, + .copy = DetailFunctionTable::Copy, + .move = DetailFunctionTable::Move, + .getPtr = DetailFunctionTable::GetPtr, + .getConstPtr = DetailFunctionTable::GetConstPtr, + }; + return &table; + } + + bool IsFunctionTableValid() const noexcept + { + return functionTable_ != nullptr; + } + + template + DecayedValueType &__attribute__((no_sanitize("cfi"))) DoEmplace(Args &&...args) + { + functionTable_ = GetFunctionTable(); + DecayedValueType* ptr = nullptr; + if (IsTrivialStackStorable::value || IsStackStorable::value) { + ptr = reinterpret_cast(functionTable_->getPtr(storage_)); + new (ptr) DecayedValueType(std::forward(args)...); + } else { + storage_.heap_ = new DecayedValueType(std::forward(args)...); + ptr = reinterpret_cast(storage_.heap_); + } + return *ptr; + } + + void __attribute__((no_sanitize("cfi"))) MoveFrom(Any &&other) noexcept + { + if (other.HasValue()) { + functionTable_ = other.functionTable_; + functionTable_->move(storage_, other.storage_); + other.Reset(); + } + } + + template + ValueType* Cast() noexcept + { + using DecayedValueType = decay_t; + if (!IsFunctionTableValid()) { + return nullptr; + } +#ifndef HST_ANY_WITH_NO_RTTI + if (!SameTypeWith(typeid(DecayedValueType))) { +#else + if (!SameTypeWith(Any::GetTypeName())) { +#endif + return nullptr; + } + return IsTrivialStackStorable::value + ? reinterpret_cast(storage_.trivialStack_.data()) + : (IsStackStorable::value + ? reinterpret_cast(&storage_.nonTrivialStack_) + : reinterpret_cast(storage_.heap_)); + } + template + const ValueType* Cast() const noexcept + { + using DecayedValueType = decay_t; + if (!IsFunctionTableValid()) { + return nullptr; + } +#ifndef HST_ANY_WITH_NO_RTTI + if (!SameTypeWith(typeid(DecayedValueType))) { +#else + if (!SameTypeWith(Any::GetTypeName())) { +#endif + return nullptr; + } + return IsTrivialStackStorable::value + ? reinterpret_cast(storage_.trivialStack_.data()) + : (IsStackStorable::value + ? reinterpret_cast(&storage_.nonTrivialStack_) + : reinterpret_cast(storage_.heap_)); + } + +private: + Storage storage_ {}; + FunctionTable* functionTable_ {nullptr}; +}; + +/** + * cast one Any pointer into ValueType pointer + * + * @tparam ValueType target value type + * @param operand any object + * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the + * const value contained by operand. + */ +template +const ValueType* AnyCast(const Any* operand) noexcept +{ + static_assert(!std::is_void::value, "ValueType of any_cast must not be void"); + if (std::is_function::value || std::is_array::value || operand == nullptr) { + return nullptr; + } + return operand->Cast(); +} + + /** + * cast one Any pointer into ValueType object + * + * @tparam ValueType target value type + * @param operand any object + * @param value ValueType + * @return false if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, true to the + * value contained by operand. + */ +template +bool AnyCast(const Any* operand, ValueType& value) noexcept +{ + static_assert(!std::is_void::value, "ValueType of any_cast must not be void"); + if (std::is_function::value || std::is_array::value || operand == nullptr) { + return false; + } +#ifndef HST_ANY_WITH_NO_RTTI + if (!operand->SameTypeWith(typeid(ValueType))) { +#else + if (!operand->SameTypeWith(Any::GetTypeName())) { +#endif + return false; + } else { + auto casted_value = operand->Cast(); + if (casted_value != nullptr) { + value = *casted_value; + return true; + } + return false; + } +} + +/** + * cast one Any pointer into ValueType pointer + * + * @tparam ValueType target value type + * @param operand any object + * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the + * value contained by operand. + */ +template +ValueType* AnyCast(Any* operand) noexcept +{ + static_assert(!std::is_void::value, "ValueType of any_cast must not be void"); + if (std::is_function::value || std::is_array::value || operand == nullptr) { + return nullptr; + } + return operand->Cast(); +} + +/** + * cast one Any object into ValueType object + * + * @tparam ValueType target value type. It must match both conditions: + * 1. ValueType must be reference or constructible + * 2. Let U be remove_cv_t>, then std::is_constructible must be true + * @param operand any object + * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, + * one object of ValueType contained in Any. + */ +template +ValueType AnyCast(const Any& other) +{ + using U = remove_cv_t>; + static_assert(IsValidCast::value, "template argument must be a reference or has copy constructors"); + static_assert(std::is_constructible::value, + "any_cast(const any&) requires ValueType constructable from const " + "remove_cv_t>&"); + auto ptr = AnyCast(&other); + return static_cast(*ptr); +} + +/** + * cast one Any object into ValueType object + * + * @tparam ValueType target value type. It must match both conditions: + * 1. ValueType must be reference or constructible + * 2. Let U be remove_cv_t>, then std::is_constructible must be true + * @param operand any object + * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, + * one object of ValueType contained in Any. + */ +template +ValueType AnyCast(Any& other) +{ + using U = remove_cv_t>; + static_assert(IsValidCast::value, "template argument must be a reference or has copy constructors"); + static_assert(std::is_constructible::value, + "any_cast(const any&) requires ValueType constructable from " + "remove_cv_t>&"); + auto ptr = AnyCast(&other); + return static_cast(*ptr); +} + +/** + * cast one Any object into ValueType object + * + * @tparam ValueType target value type. It must match both conditions: + * 1. ValueType must be reference or constructible + * 2. Let U be remove_cv_t>, then std::is_constructible must be true + * @param operand any object + * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, + * one object of ValueType contained in Any. + */ +template +ValueType AnyCast(Any&& other) +{ + using U = remove_cv_t>; + static_assert(IsValidCast::value, "template argument must be a reference or has copy constructors"); + static_assert(std::is_constructible::value, + "any_cast(const any&) requires ValueType constructable from " + "remove_cv_t>"); + auto ptr = AnyCast(&other); + return static_cast(std::move(*ptr)); +} + +/** + * Constructs Any object, whose content is constructed by args. The content type is T. + * + * @tparam T type of Any's content + * @tparam Args type of args + * @param args args used to construct the content + * @return Any object + */ +template +Any MakeAny(Args&&... args) +{ + Any tmp; + tmp.Emplace(std::forward(args)...); + return tmp; +} + +/** + * Constructs Any object, whose content is constructed by il and args. The content type is T. + * + * @tparam T type of Any's content + * @tparam U type of initializer list + * @tparam Args type of args + * @param il initializer list + * @param args args + * @return Any object + */ +template +Any MakeAny(std::initializer_list il, Args&&... args) +{ + Any tmp; + tmp.Emplace(il, std::forward(args)...); + return tmp; +} + +template +inline typename std::enable_if::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel +& parcel) +{ + if (sizeof(T) == sizeof(int64_t)) { + value.Emplace(static_cast(parcel.ReadInt64())); + return true; + } + value.Emplace(static_cast(parcel.ReadInt32())); + return true; +} +} // namespace Media +} // namespace OHOS +#endif +namespace std { +inline void swap(OHOS::Media::Any& lhs, OHOS::Media::Any& rhs) noexcept +{ + lhs.Swap(rhs); +} +} // namespace std +#endif // HISTREAMER_PLUGIN_COMMON_ANY_H \ No newline at end of file diff --git a/interfaces/inner_api/native/common/type_cast_ext.h b/interfaces/inner_api/native/common/type_cast_ext.h new file mode 100644 index 0000000..82bf354 --- /dev/null +++ b/interfaces/inner_api/native/common/type_cast_ext.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HISTREAMER_PLUGIN_TYPE_INFO_EXT_H +#define HISTREAMER_PLUGIN_TYPE_INFO_EXT_H + +#include +#include +#include +#include +#include + +namespace OHOS { +namespace Media { +#ifndef HST_ANY_WITH_NO_RTTI +/** + * This function is used to compare two type_info. Besides the basic compare using operator == of type_info, + * we also consider types with the same names are the same types. + * @param t1 type + * @param t2 type + * @return true if t1 and t2 are the same type. otherwise, false. + */ +inline bool IsSameType(const std::type_info &t1, const std::type_info &t2) noexcept +{ + if (t1 == t2) { + return true; + } + auto t1Length = strlen(t1.name()); + if (t1Length == strlen(t2.name()) && strncmp(t1.name(), t2.name(), t1Length) == 0) { + return true; + } + return false; +} +#else +inline bool IsSameType(std::string_view t1, std::string_view t2) noexcept +{ + return std::string(t1) == std::string(t2); +} +#endif + +/** + * This function is used to reinterpret cast one shared_ptr into another shared_ptr. + * @tparam T type + * @tparam U type + * @param ptr pointer + * @return cast result + */ +template +inline std::shared_ptr ReinterpretPointerCast(const std::shared_ptr &ptr) noexcept +{ + return std::shared_ptr(ptr, reinterpret_cast(ptr.get())); +} +} // Media +} // OHOS + +#endif // HISTREAMER_PLUGIN_TYPE_INFO_EXT_H \ No newline at end of file -- Gitee From 0c5a6c024541fc11437a606ae67f55778fac7384 Mon Sep 17 00:00:00 2001 From: m30063213 Date: Mon, 18 Aug 2025 11:02:02 +0800 Subject: [PATCH 02/17] =?UTF-8?q?impl=5F=20=E9=98=B2=E6=8A=A4=20Signed-off?= =?UTF-8?q?-by:=20maqianli=20<15735184237@163.com>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frameworks/native/effect/base/image_effect_inner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/native/effect/base/image_effect_inner.cpp b/frameworks/native/effect/base/image_effect_inner.cpp index 469f5b0..69761a1 100644 --- a/frameworks/native/effect/base/image_effect_inner.cpp +++ b/frameworks/native/effect/base/image_effect_inner.cpp @@ -1280,6 +1280,7 @@ void ImageEffect::ProcessSwapBuffers(BufferProcessInfo& bufferProcessInfo, int64 EFFECT_LOGD("ProcessSwapBuffers: inBuffer: %{public}d, outBuffer: %{public}d", inBuffer->GetSeqNum(), outBuffer->GetSeqNum()); + CHECK_AND_RETURN_LOG(impl_ != nullptr, "ProcessSwapBuffers: impl_ is nullptr"); ret = impl_->DetachConsumerSurfaceBuffer(inBuffer); if (ret != GSError::GSERROR_OK) { EFFECT_LOGE("ProcessSwapBuffers: DetachConsumerSurfaceBuffer failed. %{public}d", ret); -- Gitee From 445d864d2aeeecf491fdec36646f81cf40659d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E5=8D=83=E9=87=8C?= Date: Mon, 18 Aug 2025 04:09:12 +0000 Subject: [PATCH 03/17] update frameworks/native/effect/base/image_effect_inner.cpp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 马千里 --- frameworks/native/effect/base/image_effect_inner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/native/effect/base/image_effect_inner.cpp b/frameworks/native/effect/base/image_effect_inner.cpp index 69761a1..d7e4e33 100644 --- a/frameworks/native/effect/base/image_effect_inner.cpp +++ b/frameworks/native/effect/base/image_effect_inner.cpp @@ -1280,7 +1280,7 @@ void ImageEffect::ProcessSwapBuffers(BufferProcessInfo& bufferProcessInfo, int64 EFFECT_LOGD("ProcessSwapBuffers: inBuffer: %{public}d, outBuffer: %{public}d", inBuffer->GetSeqNum(), outBuffer->GetSeqNum()); - CHECK_AND_RETURN_LOG(impl_ != nullptr, "ProcessSwapBuffers: impl_ is nullptr"); + CHECK_AND_RETURN_LOG(impl_, "ProcessSwapBuffers: impl_ is nullptr"); ret = impl_->DetachConsumerSurfaceBuffer(inBuffer); if (ret != GSError::GSERROR_OK) { EFFECT_LOGE("ProcessSwapBuffers: DetachConsumerSurfaceBuffer failed. %{public}d", ret); -- Gitee From 495a2ddafd8930cdd5ea89bcd12c0d6ae554c538 Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Mon, 18 Aug 2025 13:15:00 +0000 Subject: [PATCH 04/17] =?UTF-8?q?=E5=BC=80=E6=BA=90=E4=BB=93image=5Feffect?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0any.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- bundle.json | 1 - frameworks/native/BUILD.gn | 3 +- frameworks/native/utils/common/any.cpp | 198 +++++++++++++++++++++++++ test/unittest/BUILD.gn | 1 + 4 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 frameworks/native/utils/common/any.cpp diff --git a/bundle.json b/bundle.json index 8bf6132..bb80e19 100644 --- a/bundle.json +++ b/bundle.json @@ -36,7 +36,6 @@ "libexif", "qos_manager", "video_processing_engine", - "media_foundation", "skia" ], "third_party": [ diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn index b545dac..d0e95bf 100644 --- a/frameworks/native/BUILD.gn +++ b/frameworks/native/BUILD.gn @@ -111,6 +111,7 @@ ohos_shared_library("image_effect_impl") { "$image_effect_root_dir/frameworks/native/utils/common/effect_json_helper.cpp", "$image_effect_root_dir/frameworks/native/utils/common/memcpy_helper.cpp", "$image_effect_root_dir/frameworks/native/utils/common/string_helper.cpp", + "$image_effect_root_dir/frameworks/native/utils/common/any.cpp", "$image_effect_root_dir/frameworks/native/utils/dfx/error_code.cpp", "$image_effect_root_dir/frameworks/native/utils/dfx/event_report.cpp", "$image_effect_root_dir/frameworks/native/utils/format/format_helper.cpp", @@ -137,7 +138,6 @@ ohos_shared_library("image_effect_impl") { "libexif:libexif", "napi:ace_napi", "qos_manager:qos", - "media_foundation:media_foundation", "skia:skia_canvaskit", ] @@ -201,7 +201,6 @@ ohos_shared_library("image_effect") { "image_framework:picture", "image_framework:pixelmap", "napi:ace_napi", - "media_foundation:media_foundation", ] cflags_cc = [ diff --git a/frameworks/native/utils/common/any.cpp b/frameworks/native/utils/common/any.cpp new file mode 100644 index 0000000..ca9ce8f --- /dev/null +++ b/frameworks/native/utils/common/any.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +#include "any.h" +#include + +namespace { +using namespace OHOS::Media; +using BaseTypesMap = std::map; + +const BaseTypesMap &GetBaseTypesMap() +{ + static const BaseTypesMap baseTypeMap([]() { + BaseTypesMap typeMap; + Any defaultBool = (bool)true; + typeMap[std::string(defaultBool.TypeName())] = AnyValueType::BOOL; + Any defaultInt32 = (int32_t)0; + typeMap[std::string(defaultInt32.TypeName())] = AnyValueType::INT32_T; + Any defaultInt64 = (int64_t)0; + typeMap[std::string(defaultInt64.TypeName())] = AnyValueType::INT64_T; + Any defaultFoalt = (float)0.0; + typeMap[std::string(defaultFoalt.TypeName())] = AnyValueType::FLOAT; + Any defaultDouble = (double)0.0; + typeMap[std::string(defaultDouble.TypeName())] = AnyValueType::DOUBLE; + Any defaultString = std::string(); + typeMap[std::string(defaultString.TypeName())] = AnyValueType::STRING; + Any defaultVecUint8 = std::vector(); + typeMap[std::string(defaultVecUint8.TypeName())] = AnyValueType::VECTOR_UINT8; + Any defaultVecInt32 = std::vector(); + typeMap[std::string(defaultVecInt32.TypeName())] = AnyValueType::VECTOR_INT32; + return typeMap; + }()); + return baseTypeMap; +} +} // namespace + +namespace OHOS { +namespace Media { +bool Any::BaseTypesToParcel(const Any *operand, MessageParcel &parcel) noexcept +{ + auto iter = GetBaseTypesMap().find(std::string(operand->TypeName())); + if (iter == GetBaseTypesMap().end()) { + parcel.WriteInt32(static_cast(AnyValueType::INVALID_TYPE)); + return false; + } + bool ret = parcel.WriteInt32(static_cast(iter->second)); + switch (iter->second) { + case AnyValueType::BOOL: + ret = ret && parcel.WriteBool(*AnyCast(operand)); + break; + case AnyValueType::INT32_T: + ret = ret && parcel.WriteInt32(*AnyCast(operand)); + break; + case AnyValueType::INT64_T: + ret = ret && parcel.WriteInt64(*AnyCast(operand)); + break; + case AnyValueType::FLOAT: + ret = ret && parcel.WriteFloat(*AnyCast(operand)); + break; + case AnyValueType::DOUBLE: + ret = ret && parcel.WriteDouble(*AnyCast(operand)); + break; + case AnyValueType::STRING: + ret = ret && parcel.WriteString(*AnyCast(operand)); + break; + case AnyValueType::VECTOR_UINT8: + ret = ret && parcel.WriteUInt8Vector(*AnyCast>(operand)); + break; + case AnyValueType::VECTOR_INT32: + ret = ret && parcel.WriteInt32Vector(*AnyCast>(operand)); + break; + default: { + parcel.WriteInt32(static_cast(AnyValueType::INVALID_TYPE)); + return false; + } + } + return ret; +} + +enum class StatusCodeFromParcel { + SUCCESS = 0, + ENUM_RETRY = 1, + NO_RETRY = 2, +}; + +static void BaseTypesVectorUint8(Any *operand, MessageParcel &parcel) +{ + std::vector val; + (void)parcel.ReadUInt8Vector(&val); + Any tmp(val); + operand->Swap(tmp); +} + +static void BaseTypesVectorInt32(Any *operand, MessageParcel &parcel) +{ + std::vector val; + (void)parcel.ReadInt32Vector(&val); + Any tmp(val); + operand->Swap(tmp); +} + +// returnValue : 0 -- success; 1 -- retry for enum type; 2 -- failed no retry +int Any::BaseTypesFromParcel(Any *operand, MessageParcel &parcel) noexcept +{ + AnyValueType type = static_cast(parcel.ReadInt32()); + switch (type) { + case AnyValueType::BOOL: { + Any tmp(parcel.ReadBool()); + operand->Swap(tmp); + break; + } + case AnyValueType::INT32_T: { + Any tmp(parcel.ReadInt32()); + operand->Swap(tmp); + break; + } + case AnyValueType::INT64_T: { + Any tmp(parcel.ReadInt64()); + operand->Swap(tmp); + break; + } + case AnyValueType::FLOAT: { + Any tmp(parcel.ReadFloat()); + operand->Swap(tmp); + break; + } + case AnyValueType::DOUBLE: { + Any tmp(parcel.ReadDouble()); + operand->Swap(tmp); + break; + } + case AnyValueType::STRING: { + Any tmp(parcel.ReadString()); + operand->Swap(tmp); + break; + } + case AnyValueType::VECTOR_UINT8: { + BaseTypesVectorUint8(operand, parcel); + break; + } + case AnyValueType::VECTOR_INT32: { + BaseTypesVectorInt32(operand, parcel); + break; + } + case AnyValueType::INVALID_TYPE: + return static_cast(StatusCodeFromParcel::ENUM_RETRY); + default: + return static_cast(StatusCodeFromParcel::NO_RETRY); + } + return static_cast(StatusCodeFromParcel::SUCCESS); +} + +/** + * Get TypeName From function info. + * Extract the Type name out of Function Info + * @param functionInfo Function Info + * @return Name of Type T ,Such as bool int float double std::vector etc. + * @example In windows with MEDIA_NO_OHOS define, + * FunctionInfo will be like
+ * static constexpr std::string_view OHOS::Media::Any::GetTypeName() + * [with T = bool; std::string_view = std::basic_string_view]
+ * with MEDIA_OHOS define, FunctionInfo will be like
+ * static std::string_view OHOS::Media::Any::GetTypeName() [T = std::vector]
+ * For EnumType , FunctionInfo will be like
+ * static std::string_view OHOS::Media::Any::GetTypeName() [T = OHOS::Media::Plugins::VideoEncodeBitrateMode] + */ +std::string_view Any::GetTypeNameFromFunctionInfo(const char* functionInfo) noexcept +{ + std::string_view stringInfo = functionInfo; + std::string_view retType = "Unknown"; + size_t beginIndex = stringInfo.find_first_of('='); + if (beginIndex == std::string::npos) { + return retType; + } else { + beginIndex += 2; // 2 表示右移两位 + } +#ifdef MEDIA_OHOS + size_t endIndex = stringInfo.find_last_of(']'); +#else + size_t endIndex = stringInfo.find_last_of(';'); +#endif + std::string_view typeNameRet(functionInfo + beginIndex, endIndex - beginIndex); + return typeNameRet; +} +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index df35c1b..11386ed 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -37,6 +37,7 @@ base_sources = [ "$image_effect_root_dir/frameworks/native/efilter/filterimpl/crop/crop_efilter.cpp", "$image_effect_root_dir/frameworks/native/utils/common/common_utils.cpp", "$image_effect_root_dir/frameworks/native/utils/common/effect_json_helper.cpp", + "$image_effect_root_dir/frameworks/native/utils/common/any.cpp", "$image_effect_root_dir/frameworks/native/utils/dfx/error_code.cpp", ] -- Gitee From 89d99c0a8afe20ca605426f7ae9720804e96e43d Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Mon, 18 Aug 2025 13:28:20 +0000 Subject: [PATCH 05/17] =?UTF-8?q?image=5Feffect=E5=A2=9E=E5=8A=A0any.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- frameworks/native/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn index d0e95bf..aa42ec8 100644 --- a/frameworks/native/BUILD.gn +++ b/frameworks/native/BUILD.gn @@ -185,6 +185,7 @@ ohos_shared_library("image_effect") { "$image_effect_root_dir/frameworks/native/capi/image_effect.cpp", "$image_effect_root_dir/frameworks/native/capi/image_effect_filter.cpp", "$image_effect_root_dir/frameworks/native/capi/native_common_utils.cpp", + "$image_effect_root_dir/frameworks/native/utils/common/any.cpp", ] use_exceptions = true -- Gitee From 033037fa50b8265d380f97eb709408ca0fe89041 Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Mon, 18 Aug 2025 13:43:01 +0000 Subject: [PATCH 06/17] =?UTF-8?q?image=5Feffect=E5=A2=9E=E5=8A=A0any.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- test/unittest/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 11386ed..a717f28 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -104,7 +104,6 @@ ohos_unittest("image_effect_unittest") { "libexif:libexif", "googletest:gmock_main", "googletest:gtest_main", - "media_foundation:media_foundation", ] use_exceptions = true -- Gitee From c201a3dd73d936537438f718e45c6993ee6b08de Mon Sep 17 00:00:00 2001 From: xuxc Date: Tue, 26 Aug 2025 15:08:46 +0800 Subject: [PATCH 07/17] upgrade register using sptr Signed-off-by: xuxc --- .../effect/base/effect_surface_adapter.cpp | 51 ++++++++++++------- .../effect/base/effect_surface_adapter.h | 13 ++++- .../native/effect/base/image_effect_inner.cpp | 12 +++-- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/frameworks/native/effect/base/effect_surface_adapter.cpp b/frameworks/native/effect/base/effect_surface_adapter.cpp index 007e829..e55d47b 100644 --- a/frameworks/native/effect/base/effect_surface_adapter.cpp +++ b/frameworks/native/effect/base/effect_surface_adapter.cpp @@ -33,13 +33,7 @@ EffectSurfaceAdapter::EffectSurfaceAdapter() EffectSurfaceAdapter::~EffectSurfaceAdapter() { - if (receiverConsumerSurface_) { - GSError result = receiverConsumerSurface_->UnregisterConsumerListener(); - EFFECT_LOGI("EffectSurfaceAdapter::~EffectSurfaceAdapter UnregisterConsumerListener. result=%{public}d", - result); - effectSurfaceFlag_ = DESTRUCTOR_EFFECT_SURFACE_CONSTANT; - receiverConsumerSurface_ = nullptr; - } + Destroy(); } ErrorCode EffectSurfaceAdapter::Initialize() @@ -63,9 +57,6 @@ ErrorCode EffectSurfaceAdapter::Initialize() return ErrorCode::ERR_IMAGE_EFFECT_RECEIVER_INIT_FAILED; } - // register consumer listener - receiverConsumerSurface_->RegisterConsumerListener(this); - auto surfaceUtils = SurfaceUtils::GetInstance(); auto ret = surfaceUtils->Add(fromProducerSurface_->GetUniqueId(), fromProducerSurface_); if (ret != SurfaceError::SURFACE_ERROR_OK) { @@ -80,17 +71,28 @@ ErrorCode EffectSurfaceAdapter::Initialize() sptr EffectSurfaceAdapter::GetProducerSurface() { - if (fromProducerSurface_) { - return fromProducerSurface_; - } + CHECK_AND_RETURN_RET_LOG(!fromProducerSurface_, fromProducerSurface_, + "EffectSurfaceAdapter::GetProducerSurface producerSurface exists."); - if (Initialize() != ErrorCode::SUCCESS) { - return nullptr; - } + auto ret = Initialize(); + CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, + "EffectSurfaceAdapter::GetProducerSurface Initialize failed."); return fromProducerSurface_; } +sptr EffectSurfaceAdapter::GetReceiverSurface() +{ + CHECK_AND_RETURN_RET_LOG(!receiverConsumerSurface_, receiverConsumerSurface_, + "EffectSurfaceAdapter::GetReceiverSurface consumerSurface exists."); + + auto ret = Initialize(); + CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, + "EffectSurfaceAdapter::GetReceiverSurface Initialize failed."); + + return receiverConsumerSurface_; +} + bool EffectSurfaceAdapter::CheckEffectSurface() const { return effectSurfaceFlag_ == STRUCT_EFFECT_SURFACE_CONSTANT; @@ -102,9 +104,9 @@ sptr EffectSurfaceAdapter::GetConsumerSurface() return receiverConsumerSurface_; } - if (Initialize() != ErrorCode::SUCCESS) { - return nullptr; - } + auto ret = Initialize(); + CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, + "EffectSurfaceAdapter::GetConsumerSurface Initialize failed."); return receiverConsumerSurface_; } @@ -191,6 +193,17 @@ void EffectSurfaceAdapter::OnCleanCache(uint32_t* bufSeqNum) { (void)bufSeqNum; } + +void EffectSurfaceAdapter::Destroy() +{ + if (receiverConsumerSurface_) { + GSError result = receiverConsumerSurface_->UnregisterConsumerListener(); + EFFECT_LOGI("EffectSurfaceAdapter::Destroy UnregisterConsumerListener. result=%{public}d", + result); + effectSurfaceFlag_ = DESTRUCTOR_EFFECT_SURFACE_CONSTANT; + receiverConsumerSurface_ = nullptr; + } +} } } } \ No newline at end of file diff --git a/frameworks/native/effect/base/effect_surface_adapter.h b/frameworks/native/effect/base/effect_surface_adapter.h index c16dd64..d9100f1 100644 --- a/frameworks/native/effect/base/effect_surface_adapter.h +++ b/frameworks/native/effect/base/effect_surface_adapter.h @@ -32,7 +32,7 @@ using ConsumerBufferAvailable = std::function; /** * Adapter class for image effect surface operation. */ -class EffectSurfaceAdapter : public IBufferConsumerListenerClazz { +class EffectSurfaceAdapter : public IBufferConsumerListener { public: IMAGE_EFFECT_EXPORT EffectSurfaceAdapter(); IMAGE_EFFECT_EXPORT ~EffectSurfaceAdapter(); @@ -43,6 +43,12 @@ public: */ IMAGE_EFFECT_EXPORT sptr GetProducerSurface(); + /** + * Retrieves the receiver surface. + * @return Smart pointer to the receiver surface. + */ + IMAGE_EFFECT_EXPORT sptr GetReceiverSurface(); + /** * Checks if the effect surface is valid. * @return True if valid, false otherwise. @@ -137,6 +143,11 @@ public: void OnCleanCache(uint32_t* bufSeqNum) override; // Implementation of IBufferConsumerListener interface end + /** + * Deconstructor. + */ + void Destroy(); + private: /** * Initializes the EffectSurfaceAdapter. diff --git a/frameworks/native/effect/base/image_effect_inner.cpp b/frameworks/native/effect/base/image_effect_inner.cpp index d7e4e33..f709340 100644 --- a/frameworks/native/effect/base/image_effect_inner.cpp +++ b/frameworks/native/effect/base/image_effect_inner.cpp @@ -83,7 +83,7 @@ private: void InitEffectContext(); public: - std::unique_ptr surfaceAdapter_; + sptr surfaceAdapter_; std::shared_ptr pipeline_; std::shared_ptr srcFilter_; std::shared_ptr sinkFilter_; @@ -242,7 +242,9 @@ ImageEffect::~ImageEffect() EFFECT_LOGE("ImageEffect::SwapBuffers attach fail %{public}d times", failureCount_); } imageEffectFlag_ = DESTRUCTOR_IMAGE_EFFECT_CONSTANT; - impl_->surfaceAdapter_ = nullptr; + if (impl_->surfaceAdapter_) { + impl_->surfaceAdapter_->Destroy(); + } m_renderThread->ClearTask(); auto task = std::make_shared>([this]() { this->DestroyEGLEnv(); }, COMMON_TASK_TAG, RequestTaskId()); @@ -1019,7 +1021,7 @@ ErrorCode ImageEffect::SetOutputSurface(sptr& surface) toProducerSurface_ = surface; if (impl_->surfaceAdapter_ == nullptr) { - impl_->surfaceAdapter_ = std::make_unique(); + impl_->surfaceAdapter_ = sptr::MakeSptr(); } impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage()); @@ -1382,7 +1384,7 @@ sptr ImageEffect::GetInputSurface() } if (impl_->surfaceAdapter_ == nullptr) { - impl_->surfaceAdapter_ = std::make_unique(); + impl_->surfaceAdapter_ = sptr::MakeSptr(); } if (impl_->surfaceAdapter_) { @@ -1419,7 +1421,7 @@ ErrorCode ImageEffect::SetOutNativeWindow(OHNativeWindow *nativeWindow) outDateInfo_.dataType_ = DataType::NATIVE_WINDOW; impl_->effectContext_->renderEnvironment_->InitEngine(nativeWindow); if (impl_->surfaceAdapter_ == nullptr) { - impl_->surfaceAdapter_ = std::make_unique(); + impl_->surfaceAdapter_ = sptr::MakeSptr(); } impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage()); -- Gitee From 02b3666e890d07691cb7a0851b2336f806def365 Mon Sep 17 00:00:00 2001 From: xuxc Date: Wed, 27 Aug 2025 10:19:51 +0800 Subject: [PATCH 08/17] fix consumerSurface register Signed-off-by: xuxc --- .../effect/base/effect_surface_adapter.cpp | 19 +++---------------- .../native/effect/base/image_effect_inner.cpp | 4 ++++ 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/frameworks/native/effect/base/effect_surface_adapter.cpp b/frameworks/native/effect/base/effect_surface_adapter.cpp index e55d47b..5912166 100644 --- a/frameworks/native/effect/base/effect_surface_adapter.cpp +++ b/frameworks/native/effect/base/effect_surface_adapter.cpp @@ -81,14 +81,14 @@ sptr EffectSurfaceAdapter::GetProducerSurface() return fromProducerSurface_; } -sptr EffectSurfaceAdapter::GetReceiverSurface() +sptr EffectSurfaceAdapter::GetConsumerSurface() { CHECK_AND_RETURN_RET_LOG(!receiverConsumerSurface_, receiverConsumerSurface_, - "EffectSurfaceAdapter::GetReceiverSurface consumerSurface exists."); + "EffectSurfaceAdapter::GetConsumerSurface consumerSurface exists."); auto ret = Initialize(); CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, - "EffectSurfaceAdapter::GetReceiverSurface Initialize failed."); + "EffectSurfaceAdapter::GetConsumerSurface Initialize failed."); return receiverConsumerSurface_; } @@ -98,19 +98,6 @@ bool EffectSurfaceAdapter::CheckEffectSurface() const return effectSurfaceFlag_ == STRUCT_EFFECT_SURFACE_CONSTANT; } -sptr EffectSurfaceAdapter::GetConsumerSurface() -{ - if (receiverConsumerSurface_) { - return receiverConsumerSurface_; - } - - auto ret = Initialize(); - CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, - "EffectSurfaceAdapter::GetConsumerSurface Initialize failed."); - - return receiverConsumerSurface_; -} - GSError EffectSurfaceAdapter::AcquireConsumerSurfaceBuffer(sptr& buffer, sptr& syncFence, int64_t& timestamp, OHOS::Rect& damages) const { diff --git a/frameworks/native/effect/base/image_effect_inner.cpp b/frameworks/native/effect/base/image_effect_inner.cpp index f709340..e642426 100644 --- a/frameworks/native/effect/base/image_effect_inner.cpp +++ b/frameworks/native/effect/base/image_effect_inner.cpp @@ -1397,6 +1397,10 @@ sptr ImageEffect::GetInputSurface() if (impl_->surfaceAdapter_) { impl_->surfaceAdapter_->SetConsumerListener(std::move(consumerListener)); + // register consumer listener + auto receiverConsumerSurface = impl_->surfaceAdapter_->GetConsumerSurface(); + sptr listener = impl_->surfaceAdapter_; + receiverConsumerSurface->RegisterConsumerListener(listener); } auto consumerSurface = impl_->GetConsumerSurface(); -- Gitee From f3b7647170e1fff0228db4f795c98296adb3ca5d Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Fri, 29 Aug 2025 09:41:18 +0000 Subject: [PATCH 09/17] =?UTF-8?q?image=5Feffect=20=E5=BC=80=E6=BA=90?= =?UTF-8?q?=E4=BB=93TDD=E4=B8=8A=E6=85=A7=E7=9C=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- test/unittest/BUILD.gn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index a717f28..55bd9ff 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -14,7 +14,7 @@ import("//build/test.gni") import("//foundation/multimedia/image_effect/config.gni") -module_output_path = "image_effect/image_effect_unittest" +module_output_path = "image_effect/image_effect/test" base_include_dirs = [ "$image_effect_root_dir/interfaces/inner_api/native/memory", @@ -104,6 +104,7 @@ ohos_unittest("image_effect_unittest") { "libexif:libexif", "googletest:gmock_main", "googletest:gtest_main", + "media_foundation:media_foundation", ] use_exceptions = true -- Gitee From d02f36011c6872738cdf56e6ef3beb10710ac50b Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Fri, 29 Aug 2025 09:43:21 +0000 Subject: [PATCH 10/17] =?UTF-8?q?image=5Feffect=20=E5=BC=80=E6=BA=90?= =?UTF-8?q?=E4=BB=93TDD=E4=B8=8A=E6=85=A7=E7=9C=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- test/unittest/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 55bd9ff..4a2d36f 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -104,7 +104,6 @@ ohos_unittest("image_effect_unittest") { "libexif:libexif", "googletest:gmock_main", "googletest:gtest_main", - "media_foundation:media_foundation", ] use_exceptions = true -- Gitee From e8300961af44fd0579fe72932ce31720f9f362c1 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Aug 2025 01:56:30 +0000 Subject: [PATCH 11/17] update frameworks/native/capi/image_effect.cpp. Signed-off-by: Steven --- frameworks/native/capi/image_effect.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frameworks/native/capi/image_effect.cpp b/frameworks/native/capi/image_effect.cpp index 6d1927c..864bd46 100644 --- a/frameworks/native/capi/image_effect.cpp +++ b/frameworks/native/capi/image_effect.cpp @@ -690,8 +690,7 @@ OH_ImageEffect *OH_ImageEffect_Restore(const char *info) std::unique_ptr nativeEFilter = std::make_unique(); std::shared_ptr efilter = EFilterFactory::Instance()->Restore(name, effect, nativeEFilter.get()); - CHECK_AND_RETURN_RET_LOG(efilter != nullptr, nullptr, "Restore: efilter restore fail! name=%{public}s", - name.c_str()); + CHECK_AND_RETURN_RET_LOG(efilter != nullptr, nullptr, "efilter restore fail! name=%{public}s", name.c_str()); nativeEFilter->filter_ = efilter; nativeEFilter->isCreatedBySystem_ = true; ohImageEffect->filters_.emplace_back(nativeEFilter.release(), efilter->GetName()); -- Gitee From 5d17706c7cfbcfe895bf9616322b820341c1deae Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Aug 2025 01:57:45 +0000 Subject: [PATCH 12/17] update frameworks/native/efilter/base/efilter.cpp. Signed-off-by: Steven --- frameworks/native/efilter/base/efilter.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frameworks/native/efilter/base/efilter.cpp b/frameworks/native/efilter/base/efilter.cpp index d326eb8..078eead 100644 --- a/frameworks/native/efilter/base/efilter.cpp +++ b/frameworks/native/efilter/base/efilter.cpp @@ -787,6 +787,20 @@ ErrorCode EFilter::CancelCache() return ReleaseCache(); } +ErrorCode EFilter::GetEditDataVersion(const EffectJsonPtr& values, uint32_t &editDataVersion) +{ + EFFECT_LOGI("EFilter::GetEditDataVersion in, default editDataVersion set to 1."); + editDataVersion = 1; + return ErrorCode::SUCCESS; +} + +ErrorCode EFilter::GetFilterVersion(uint32_t &filterVersion) +{ + EFFECT_LOGI("EFilter::GetFilterVersion in, default filterVersion set to 1."); + filterVersion = 1; + return ErrorCode::SUCCESS; +} + } // namespace Effect } // namespace Media } // namespace OHOS \ No newline at end of file -- Gitee From 48342116be41af203aa26910300e743e57eebd0e Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Aug 2025 02:03:56 +0000 Subject: [PATCH 13/17] update frameworks/native/efilter/base/efilter_factory.cpp. Signed-off-by: Steven --- frameworks/native/efilter/base/efilter_factory.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frameworks/native/efilter/base/efilter_factory.cpp b/frameworks/native/efilter/base/efilter_factory.cpp index d495c76..74eb6ea 100644 --- a/frameworks/native/efilter/base/efilter_factory.cpp +++ b/frameworks/native/efilter/base/efilter_factory.cpp @@ -79,8 +79,16 @@ std::shared_ptr EFilterFactory::Restore(const std::string &name, const std::shared_ptr efilter = EFilterFactory::Instance()->Create(name, handler); CHECK_AND_RETURN_RET_LOG(efilter != nullptr, nullptr, "Restore: create filter fail! name=%{public}s", name.c_str()); CHECK_AND_RETURN_RET_LOG(root->HasElement("values"), efilter, "[values] not exist!"); - const EffectJsonPtr values = root->GetElement("values"); + uint32_t editDataVersion = 1; + uint32_t filterVersion = 1; + ErrorCode ret = efilter->GetEditDataVersion(values, editDataVersion); + CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, + "Restore: GetEditDataVersion fail! name=%{public}s", name.c_str()); + ret = efilter->GetFilterVersion(filterVersion); + CHECK_AND_RETURN_RET_LOG(ret == ErrorCode::SUCCESS, nullptr, + "Restore: GetFilterVersion fail! name=%{public}s", name.c_str()); + CHECK_AND_RETURN_RET_LOG(filterVersion >= editDataVersion, nullptr, "Filter version is too low, Restore failed!"); CHECK_AND_RETURN_RET_LOG(efilter->Restore(values) == ErrorCode::SUCCESS, efilter, "values restore fail!"); return efilter; } -- Gitee From c568690ff63f261665b062b269791a629a721fa6 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Aug 2025 02:04:38 +0000 Subject: [PATCH 14/17] update interfaces/inner_api/native/efilter/efilter.h. Signed-off-by: Steven --- interfaces/inner_api/native/efilter/efilter.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/interfaces/inner_api/native/efilter/efilter.h b/interfaces/inner_api/native/efilter/efilter.h index 3e0b927..19f53b8 100644 --- a/interfaces/inner_api/native/efilter/efilter.h +++ b/interfaces/inner_api/native/efilter/efilter.h @@ -101,6 +101,13 @@ public: IMAGE_EFFECT_EXPORT virtual bool IsTextureInput(); + + IMAGE_EFFECT_EXPORT + virtual ErrorCode GetEditDataVersion(const EffectJsonPtr& values, uint32_t &editDataVersion); + + IMAGE_EFFECT_EXPORT + virtual ErrorCode GetFilterVersion(uint32_t &filterVersion); + protected: ErrorCode CalculateEFilterIPType(IEffectFormat &formatType, IPType &ipType); -- Gitee From 2a6f90a275a8ec9d114712fdaa5a9f373ee4c256 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Aug 2025 03:22:47 +0000 Subject: [PATCH 15/17] update test/unittest/image_effect_capi_unittest.cpp. Signed-off-by: Steven --- test/unittest/image_effect_capi_unittest.cpp | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/unittest/image_effect_capi_unittest.cpp b/test/unittest/image_effect_capi_unittest.cpp index 594b40d..230c5f7 100644 --- a/test/unittest/image_effect_capi_unittest.cpp +++ b/test/unittest/image_effect_capi_unittest.cpp @@ -2071,6 +2071,30 @@ HWTEST_F(ImageEffectCApiUnittest, OHImageEffectRestore003, TestSize.Level1) GTEST_LOG_(INFO) << "ImageEffectCApiUnittest: OHImageEffectRestore003 END"; } +/** + * Feature: ImageEffect + * Function: Test OH_ImageEffect_Restore with empty parameter + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Test OH_ImageEffect_Restore with empty parameter + */ +HWTEST_F(ImageEffectCApiUnittest, OHImageEffectRestore004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ImageEffectCApiUnittest: OHImageEffectRestore004 start"; + + OH_ImageEffect *imageEffect = OH_ImageEffect_Create(IMAGE_EFFECT_NAME); + ASSERT_NE(imageEffect, nullptr) << "OH_ImageEffect_Restore failed"; + char *imageEffectInfo = nullptr; + ImageEffect_ErrorCode errorCode = OH_ImageEffect_Save(imageEffect, &imageEffectInfo); + EXPECT_EQ(errorCode, ImageEffect_ErrorCode::EFFECT_SUCCESS) << "OH_ImageEffect_Restore failed"; + imageEffect = OH_ImageEffect_Restore(nullptr); + EXPECT_EQ(imageEffect, nullptr) << "OH_ImageEffect_Restore failed"; + + GTEST_LOG_(INFO) << "OHImageEffectRestore004 success! result: " << errorCode; + GTEST_LOG_(INFO) << "ImageEffectCApiUnittest: OHImageEffectRestore004 END"; +} + /** * Feature: ImageEffect * Function: Test OH_ImageEffect_SetOutputSurface with normal parameter -- Gitee From 417d259af04d2b8d75a0975388a9840d363077da Mon Sep 17 00:00:00 2001 From: lusunqi Date: Tue, 2 Sep 2025 10:06:20 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E2=80=9D=E4=BF=AE=E5=A4=8D=E4=B8=89?= =?UTF-8?q?=E6=8A=98=E5=8F=A0=E5=89=8D=E7=BD=AE=E6=8B=8D=E6=91=84=E5=85=A8?= =?UTF-8?q?=E5=B1=8F=E4=B8=AA=E6=80=A7=E8=89=B2=E5=8D=A1=E5=9B=BE=E7=89=87?= =?UTF-8?q?=EF=BC=8C=E5=86=8D=E7=BC=96=E8=BE=91=E6=97=B6=EF=BC=8C=E4=B8=AA?= =?UTF-8?q?=E6=80=A7=E8=89=B2=E5=8D=A1=E9=80=89=E9=A1=B9=E9=BB=91=E5=B1=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lusunqi --- frameworks/native/efilter/base/efilter.cpp | 37 ++++++++++++++++++- interfaces/inner_api/native/efilter/efilter.h | 3 ++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/frameworks/native/efilter/base/efilter.cpp b/frameworks/native/efilter/base/efilter.cpp index 078eead..27e09c1 100644 --- a/frameworks/native/efilter/base/efilter.cpp +++ b/frameworks/native/efilter/base/efilter.cpp @@ -283,6 +283,41 @@ std::shared_ptr EFilter::CreateEffectBufferFromTexture(const std:: return effectBuffer; } +std::shared_ptr EFilter::CreateEffectBufferFromTexture(void *addr, + const std::shared_ptr &buffer, const std::shared_ptr &context) +{ + EFFECT_LOGD("EFilter::CreateGainMapBufferFromTexture"); + auto texture = buffer->bufferInfo_->tex_; + MemoryInfo memInfo = { + .bufferInfo = { + .width_ = texture->Width(), + .height_ = texture->Height(), + .len_ = FormatHelper::CalculateSize(texture->Width(), texture->Height(), IEffectFormat::RGBA8888), + .formatType_ = IEffectFormat::RGBA8888, + }, + .bufferType = BufferType::DMA_BUFFER, + }; + + MemoryData* memoryData = context->memoryManager_->AllocMemory(addr, memInfo); + CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, buffer, "Alloc new memory fail!"); + + MemoryInfo& allocMemInfo = memoryData->memoryInfo; + auto bufferInfo = std::make_shared(); + CommonUtils::CopyBufferInfo(allocMemInfo.bufferInfo, *bufferInfo); + auto extraInfo = std::make_shared(); + CommonUtils::CopyExtraInfo(*buffer->extraInfo_, *extraInfo); + extraInfo->bufferType = allocMemInfo.bufferType; + bufferInfo->surfaceBuffer_ = static_cast(allocMemInfo.extra); + + auto effectBuffer = std::make_shared(bufferInfo, memoryData->data, extraInfo); + context->renderEnvironment_->ConvertTextureToBuffer(texture, effectBuffer.get()); + bufferInfo->surfaceBuffer_->InvalidateCache(); + effectBuffer->extraInfo_->dataType = DataType::SURFACE_BUFFER; + effectBuffer->extraInfo_->bufferType = BufferType::DMA_BUFFER; + + return effectBuffer; +} + std::shared_ptr EFilter::ConvertFromGPU2CPU(const std::shared_ptr &buffer, std::shared_ptr &context, std::shared_ptr &source) { @@ -303,7 +338,7 @@ std::shared_ptr EFilter::ConvertFromGPU2CPU(const std::shared_ptr< auto gainMapBufferInfo = gainMapBufferInfoIt->second; auto tmpGainMapBuffer = std::make_shared(gainMapBufferInfo, nullptr, input->extraInfo_); - auto gainMapBuffer = CreateEffectBufferFromTexture(tmpGainMapBuffer, context); + auto gainMapBuffer = CreateEffectBufferFromTexture(input->buffer_, tmpGainMapBuffer, context); if (!gainMapBuffer) return source; gainMapBuffer->bufferInfo_->pixelmapType_ = EffectPixelmapType::GAINMAP; diff --git a/interfaces/inner_api/native/efilter/efilter.h b/interfaces/inner_api/native/efilter/efilter.h index 19f53b8..c32f822 100644 --- a/interfaces/inner_api/native/efilter/efilter.h +++ b/interfaces/inner_api/native/efilter/efilter.h @@ -133,6 +133,9 @@ private: static std::shared_ptr CreateEffectBufferFromTexture(const std::shared_ptr &buffer, const std::shared_ptr &context); + static std::shared_ptr CreateEffectBufferFromTexture(void *addr, + const std::shared_ptr &buffer, const std::shared_ptr &context); + std::shared_ptr ConvertFromGPU2CPU(const std::shared_ptr &buffer, std::shared_ptr &context, std::shared_ptr &source); -- Gitee From 22b105c50c4e2caf5108f3933dd328e28f91dd55 Mon Sep 17 00:00:00 2001 From: zyyj208 Date: Tue, 2 Sep 2025 10:07:17 +0000 Subject: [PATCH 17/17] =?UTF-8?q?=E5=85=88=E4=B8=8B=E6=9E=B6TestRenderEnvi?= =?UTF-8?q?ronment001=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zyyj208 --- test/unittest/TestRenderEnvironment.cpp | 35 ------------------------- 1 file changed, 35 deletions(-) diff --git a/test/unittest/TestRenderEnvironment.cpp b/test/unittest/TestRenderEnvironment.cpp index 12fd396..569a870 100644 --- a/test/unittest/TestRenderEnvironment.cpp +++ b/test/unittest/TestRenderEnvironment.cpp @@ -80,41 +80,6 @@ public: std::shared_ptr renderEnvironment; }; -HWTEST_F(TestRenderEnvironment, TestRenderEnvironment001, TestSize.Level1) -{ - std::shared_ptr output; - renderEnvironment->outType_ = DataType::NATIVE_WINDOW; - effectBuffer->bufferInfo_->width_ = 2 * WIDTH; - renderEnvironment->GenTex(effectBuffer, output); - - effectBuffer->bufferInfo_->formatType_ = IEffectFormat::DEFAULT; - renderEnvironment->GenTex(effectBuffer, output); - - RenderTexturePtr texptr = renderEnvironment->RequestBuffer(WIDTH, HEIGHT); - EXPECT_NE(texptr, nullptr); - renderEnvironment->ConvertTextureToBuffer(texptr, effectBuffer.get()); - - GLenum internalFormat = GL_RG8; - size_t ret = GLUtils::GetInternalFormatPixelByteSize(internalFormat); - EXPECT_EQ(ret, 0); - - internalFormat = GL_R8; - ret = GLUtils::GetInternalFormatPixelByteSize(internalFormat); - EXPECT_EQ(ret, 1); - - internalFormat = GL_RGB565; - ret = GLUtils::GetInternalFormatPixelByteSize(internalFormat); - EXPECT_EQ(ret, 2); - - internalFormat = GL_RGBA4; - ret = GLUtils::GetInternalFormatPixelByteSize(internalFormat); - EXPECT_EQ(ret, 2); - - internalFormat = GL_RGBA16F; - ret = GLUtils::GetInternalFormatPixelByteSize(internalFormat); - EXPECT_EQ(ret, 8); -} - HWTEST_F(TestRenderEnvironment, TestRenderEnvironment002, TestSize.Level1) { IEffectFormat format = IEffectFormat::YUVNV12; -- Gitee