diff --git a/frameworks/opengl_wrapper/BUILD.gn b/frameworks/opengl_wrapper/BUILD.gn index 38435e2981..62bbdc45f4 100644 --- a/frameworks/opengl_wrapper/BUILD.gn +++ b/frameworks/opengl_wrapper/BUILD.gn @@ -25,6 +25,11 @@ config("egl_config") { } else { defines += [ "USE_IGRAPHICS_EXTENDS_HOOKS=0" ] } + if (graphic_2d_feature_use_aps_igameservice_func) { + defines += [ "USE_APS_IGAMESERVICE_FUNC=1" ] + } else { + defines += [ "USE_APS_IGAMESERVICE_FUNC=0" ] + } cflags = [ "-Wall", @@ -38,6 +43,10 @@ config("egl_public_config") { if (graphic_2d_feature_use_igraphics_extend_hooks) { include_dirs += egl_igraphics_extend_hooks_include_dirs } + if (graphic_2d_feature_use_aps_igameservice_func) { + include_dirs += aps_client_include_dirs + include_dirs += gameservice_render_slice_report_include_dirs + } } if (current_os != "ohos") { @@ -64,6 +73,10 @@ if (current_os != "ohos") { if (graphic_2d_feature_use_igraphics_extend_hooks) { sources += egl_igraphics_extend_hooks_sources } + if (graphic_2d_feature_use_aps_igameservice_func) { + sources += aps_client_sources + sources += gameservice_render_slice_report_sources + } configs = [ ":egl_config" ] public_configs = [ ":egl_public_config" ] @@ -77,6 +90,11 @@ if (current_os != "ohos") { "init:libbegetutil", ] + if (graphic_2d_feature_use_aps_igameservice_func) { + external_deps += aps_client_external_deps + external_deps += gameservice_render_slice_report_external_deps + } + if (defined(graphic_2d_ext_configs.vendor_root)) { install_enable = false } diff --git a/frameworks/opengl_wrapper/src/EGL/egl_wrapper_entry.cpp b/frameworks/opengl_wrapper/src/EGL/egl_wrapper_entry.cpp index f80c66d338..851be68510 100644 --- a/frameworks/opengl_wrapper/src/EGL/egl_wrapper_entry.cpp +++ b/frameworks/opengl_wrapper/src/EGL/egl_wrapper_entry.cpp @@ -28,6 +28,10 @@ #include "thread_private_data_ctl.h" #include "wrapper_log.h" #include "egl_blob_cache.h" +#if USE_APS_IGAMESERVICE_FUNC +#include "egl_slice_report.h" +#include "aps_game_fps_controller.h" +#endif using namespace OHOS; namespace OHOS { @@ -340,6 +344,9 @@ __eglMustCastToProperFunctionPointerType EglGetProcAddressImpl(const char *procn EGLBoolean EglInitializeImpl(EGLDisplay dpy, EGLint *major, EGLint *minor) { WLOGD(""); +#if USE_APS_IGAMESERVICE_FUNC + OHOS::GameService::EglSliceReport::GetInstance().InitSliceReport(); +#endif EglWrapperDisplay *display = EglWrapperDisplay::GetWrapperDisplay(dpy); if (!display) { WLOGE("EGLDislay is invalid."); @@ -428,6 +435,10 @@ EGLBoolean EglSwapBuffersImpl(EGLDisplay dpy, EGLSurface surf) { ClearError(); WLOGD(""); +#if USE_APS_IGAMESERVICE_FUNC + OHOS::GameService::EglSliceReport::GetInstance().AddGraphicCount(); + OHOS::Rosen::ApsGameFpsController::GetInstance().PowerCtrllofEglswapbuffer(); +#endif EglWrapperDisplay *display = ValidateDisplay(dpy); if (!display) { return EGL_FALSE; diff --git a/graphic_config.gni b/graphic_config.gni index 07cce9c025..cf52d199f4 100644 --- a/graphic_config.gni +++ b/graphic_config.gni @@ -44,6 +44,7 @@ declare_args() { graphic_2d_feature_tp_switch_enbale = false graphic_2d_feature_enable_recording_dcl = true graphic_2d_feature_use_igraphics_extend_hooks = false + graphic_2d_feature_use_aps_igameservice_func = false graphic_2d_feature_enable_chipset_vsync = false graphic_2d_feature_enable_rspipeline = false @@ -208,6 +209,15 @@ check_igraphics_core_file_args = [ rebase_path( "//vendor/huawei/foundation/graphics_game/gpu_turbo_x/EGL/config.gni"), ] +check_igameservice_core_file_args = [ + "--filename", + rebase_path( + "//vendor/huawei/domains/game/gameservice_server/performance/graphics/report/config.gni"), +] +check_aps_core_file_args = [ + "--filename", + rebase_path("//foundation/graphic/graphic_2d_ext/aps_manager/config.gni"), +] check_delegator_ext_file_args = [ "--filename", rebase_path("//foundation/graphic/graphic_2d_ext/delegator/config.gni"), @@ -239,6 +249,17 @@ if (exec_script(check_graphic_ext_file_script, graphic_2d_feature_use_igraphics_extend_hooks = true import("//vendor/huawei/foundation/graphics_game/gpu_turbo_x/EGL/config.gni") } +if (exec_script(check_graphic_ext_file_script, + check_aps_core_file_args, + "string") == "True" && + exec_script(check_graphic_ext_file_script, + check_igameservice_core_file_args, + "string") == "True") { + graphic_2d_feature_use_aps_igameservice_func = true + import("//foundation/graphic/graphic_2d_ext/aps_manager/config.gni") + import( + "//vendor/huawei/domains/game/gameservice_server/performance/graphics/report/config.gni") +} graphic_2d_delegator_configs = { } diff --git a/interfaces/inner_api/composer/vsync_receiver.h b/interfaces/inner_api/composer/vsync_receiver.h index fe6b5b3abc..7ee56da701 100644 --- a/interfaces/inner_api/composer/vsync_receiver.h +++ b/interfaces/inner_api/composer/vsync_receiver.h @@ -58,6 +58,16 @@ public: int64_t timeStamp_; thread_local static inline int64_t periodShared_ = 0; thread_local static inline int64_t timeStampShared_ = 0; + void SetRNVFlag(bool RNVFlag) + { + std::lock_guard locker(mtx_); + RNVFlag_ = RNVFlag; + } + bool GetRNVFlag() + { + std::lock_guard locker(mtx_); + return RNVFlag_; + } private: void OnReadable(int32_t fileDescriptor) override; @@ -65,6 +75,7 @@ private: void *userData_; std::mutex mtx_; std::string name_; + bool RNVFlag_ = false; }; #ifdef __OHOS__ @@ -96,6 +107,7 @@ public: void CloseVsyncReceiverFd(); virtual VsyncError RequestNextVSync(FrameCallback callback, const std::string &fromWhom, int64_t lastVSyncTS); + virtual bool IsRequestedNextVSync(); private: VsyncError Destroy(); sptr connection_; diff --git a/interfaces/inner_api/wm/window_manager_common.h b/interfaces/inner_api/wm/window_manager_common.h index 009e4a23d2..9cbb5ad5e3 100644 --- a/interfaces/inner_api/wm/window_manager_common.h +++ b/interfaces/inner_api/wm/window_manager_common.h @@ -16,7 +16,7 @@ #ifndef INTERFACES_INNERKITS_WM_WINDOW_MANAGER_COMMON_H #define INTERFACES_INNERKITS_WM_WINDOW_MANAGER_COMMON_H -#include "../wmclient/wm_common.h" +#include "wmclient/wm_common.h" namespace OHOS { typedef enum { diff --git a/interfaces/inner_api/wmclient/window_manager_type.h b/interfaces/inner_api/wmclient/window_manager_type.h index 08adbdb35d..03ee6abd55 100644 --- a/interfaces/inner_api/wmclient/window_manager_type.h +++ b/interfaces/inner_api/wmclient/window_manager_type.h @@ -23,7 +23,7 @@ #include "wm_common.h" -#include "../common/graphic_common.h" +#include "common/graphic_common.h" #ifdef __cplusplus namespace OHOS { diff --git a/interfaces/inner_api/wmclient/wm_common.h b/interfaces/inner_api/wmclient/wm_common.h index 06b0f33d1c..9f886b7dc8 100755 --- a/interfaces/inner_api/wmclient/wm_common.h +++ b/interfaces/inner_api/wmclient/wm_common.h @@ -22,7 +22,7 @@ #include #endif -#include "../common/graphic_common.h" +#include "common/graphic_common.h" #ifdef __cplusplus namespace OHOS { diff --git a/interfaces/kits/napi/graphic/text/BUILD.gn b/interfaces/kits/napi/graphic/text/BUILD.gn index a392b6888a..f23bcf514f 100755 --- a/interfaces/kits/napi/graphic/text/BUILD.gn +++ b/interfaces/kits/napi/graphic/text/BUILD.gn @@ -79,6 +79,7 @@ ohos_shared_library("text_napi_impl") { "graphic_surface:surface", "hilog:libhilog", "napi:ace_napi", + "resource_management:global_resmgr", ] if (current_os == "ohos" || current_os == "ohos_ng") { diff --git a/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.cpp b/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.cpp index 86b3e30eac..0f7fcec5fd 100755 --- a/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.cpp +++ b/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.cpp @@ -14,19 +14,23 @@ */ #include +#include "js_drawing_utils.h" #include "js_fontcollection.h" namespace OHOS::Rosen { constexpr size_t FILE_HEAD_LENGTH = 7; // 7 is the size of "file://" thread_local napi_ref JsFontCollection::constructor_ = nullptr; const std::string CLASS_NAME = "FontCollection"; +const std::string LOCAL_BIND_PATH = "/data/storage/el1/bundle/"; +const std::string HAP_POSTFIX = ".hap"; +const int32_t GLOBAL_ERROR = 10000; napi_value JsFontCollection::Constructor(napi_env env, napi_callback_info info) { size_t argCount = 0; napi_value jsThis = nullptr; napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr); if (status != napi_ok) { - LOGE("failed from napi_get_cb_info"); + ROSEN_LOGE("failed from napi_get_cb_info"); return nullptr; } @@ -35,7 +39,7 @@ napi_value JsFontCollection::Constructor(napi_env env, napi_callback_info info) JsFontCollection::Destructor, nullptr, nullptr); if (status != napi_ok) { delete jsFontCollection; - LOGE("Failed from napi_wrap"); + ROSEN_LOGE("failed from napi_wrap"); return nullptr; } return jsThis; @@ -112,7 +116,7 @@ bool JsFontCollection::SpiltAbsoluteFontPath(std::string& absolutePath) { auto iter = absolutePath.find_first_of(':'); if (iter == std::string::npos) { - LOGE("Font file directory is not absolute path"); + ROSEN_LOGE("font file directory is not absolute path"); return false; } std::string head = absolutePath.substr(0, iter); @@ -125,6 +129,150 @@ bool JsFontCollection::SpiltAbsoluteFontPath(std::string& absolutePath) return false; } +std::unique_ptr JsFontCollection::GetResourManager(const std::string& moudleName) +{ + auto hapPath = LOCAL_BIND_PATH + moudleName + HAP_POSTFIX; + auto resManager = Global::Resource::CreateResourceManager(); + if (!resManager) { + return nullptr; + } + resManager->AddResource(hapPath.c_str()); + return std::unique_ptr(resManager); +} + +bool JsFontCollection::GetResourcePartData(napi_env env, ResourceInfo& info, napi_value paramsNApi, + napi_value bundleNameNApi, napi_value moduleNameNApi) +{ + napi_valuetype valueType = napi_undefined; + bool isArray = false; + if (napi_is_array(env, paramsNApi, &isArray) != napi_ok) { + return false; + } + if (!isArray) { + return false; + } + + uint32_t arrayLength = 0; + napi_get_array_length(env, paramsNApi, &arrayLength); + for (uint32_t i = 0; i < arrayLength; i++) { + size_t ret = 0; + napi_value indexValue = nullptr; + napi_get_element(env, paramsNApi, i, &indexValue); + napi_typeof(env, indexValue, &valueType); + if (valueType == napi_string) { + size_t strLen = GetParamLen(env, indexValue) + 1; + std::unique_ptr indexStr = std::make_unique(strLen); + napi_get_value_string_utf8(env, indexValue, indexStr.get(), strLen, &ret); + info.params.emplace_back(indexStr.get()); + } else if (valueType == napi_number) { + int32_t num; + napi_get_value_int32(env, indexValue, &num); + info.params.emplace_back(std::to_string(num)); + } else { + ROSEN_LOGE("invalid argument"); + } + } + + napi_typeof(env, bundleNameNApi, &valueType); + if (valueType == napi_string) { + size_t ret = 0; + size_t strLen = GetParamLen(env, bundleNameNApi) + 1; + std::unique_ptr bundleNameStr = std::make_unique(strLen); + napi_get_value_string_utf8(env, bundleNameNApi, bundleNameStr.get(), strLen, &ret); + info.bundleName = bundleNameStr.get(); + } + + napi_typeof(env, moduleNameNApi, &valueType); + if (valueType == napi_string) { + size_t ret = 0; + size_t strLen = GetParamLen(env, moduleNameNApi) + 1; + std::unique_ptr moduleNameStr = std::make_unique(strLen); + napi_get_value_string_utf8(env, moduleNameNApi, moduleNameStr.get(), strLen, &ret); + info.moduleName = moduleNameStr.get(); + } + + return true; +} + +bool JsFontCollection::ParseResourceType(napi_env env, napi_value value, ResourceInfo& info) +{ + napi_value idNApi = nullptr; + napi_value typeNApi = nullptr; + napi_value paramsNApi = nullptr; + napi_value bundleNameNApi = nullptr; + napi_value moduleNameNApi = nullptr; + napi_valuetype valueType = napi_undefined; + napi_typeof(env, value, &valueType); + if (valueType == napi_object) { + napi_get_named_property(env, value, "id", &idNApi); + napi_get_named_property(env, value, "type", &typeNApi); + napi_get_named_property(env, value, "params", ¶msNApi); + napi_get_named_property(env, value, "bundleName", &bundleNameNApi); + napi_get_named_property(env, value, "moduleName", &moduleNameNApi); + } else { + return false; + } + + napi_typeof(env, idNApi, &valueType); + if (valueType == napi_number) { + napi_get_value_int32(env, idNApi, &info.resId); + } + + napi_typeof(env, typeNApi, &valueType); + if (valueType == napi_number) { + napi_get_value_int32(env, typeNApi, &info.type); + } + if (!GetResourcePartData(env, info, paramsNApi, bundleNameNApi, moduleNameNApi)) { + return false; + } + + return true; +} + +bool JsFontCollection::ParseResourcePath(napi_env env, napi_value value, const std::string familyName) +{ + ResourceInfo info; + if (!ParseResourceType(env, value, info)) { + return false; + } + int32_t state = 0; + + auto reSourceManager = GetResourManager(info.moduleName); + if (reSourceManager == nullptr) { + return false; + } + if (info.type == static_cast(ResourceType::STRING)) { + std::string rPath; + if (info.resId < 0 && info.params[0].size() > 0) { + rPath = info.params[0]; + } else { + state = reSourceManager->GetStringById(info.resId, rPath); + if (state >= GLOBAL_ERROR || state < 0) { + return false; + } + if (!SpiltAbsoluteFontPath(rPath) || !GetFontFileProperties(rPath, familyName)) { + return false; + } + } + } else if (info.type == static_cast(ResourceType::RAWFILE)) { + size_t dataLen = 0; + std::unique_ptr rawData; + state = reSourceManager->GetRawFileFromHap(info.params[0], dataLen, rawData); + if (state >= GLOBAL_ERROR || state < 0) { + return false; + } + Drawing::Typeface* typeface = m_fontCollection->LoadFont(familyName.c_str(), rawData.get(), dataLen); + if (typeface == nullptr || !AddTypefaceInformation(typeface, familyName)) { + return false; + } + return true; + } else { + ROSEN_LOGE("incorrect path type of font file"); + return false; + } + return true; +} + Drawing::Typeface* JsFontCollection::GetFontFileProperties(const std::string path, const std::string familyName) { size_t datalen; @@ -213,6 +361,11 @@ napi_value JsFontCollection::OnLoadFont(napi_env env, napi_callback_info info) } return NapiGetUndefined(env); } + + if (!ParseResourcePath(env, argv[1], familyName)) { + return nullptr; + } + return NapiGetUndefined(env); } } // namespace OHOS::Rosen diff --git a/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.h b/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.h index 67ee445a95..b06dee1c89 100755 --- a/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.h +++ b/interfaces/kits/napi/graphic/text/fontcollection_napi/js_fontcollection.h @@ -18,8 +18,10 @@ #include #include +#include "resource_manager.h" #include "font_collection.h" #include "js_text_utils.h" +#include namespace OHOS::Rosen { class JsFontCollection final { @@ -37,7 +39,12 @@ private: static thread_local napi_ref constructor_; napi_value OnDisableFallback(napi_env env, napi_callback_info info); napi_value OnLoadFont(napi_env env, napi_callback_info info); + std::unique_ptr GetResourManager(const std::string& moudleName); bool SpiltAbsoluteFontPath(std::string& absolutePath); + bool ParseResourcePath(napi_env env, napi_value value, const std::string familyName); + bool ParseResourceType(napi_env env, napi_value value, ResourceInfo& info); + bool GetResourcePartData(napi_env env, ResourceInfo& info, napi_value paramsNApi, + napi_value bundleNameNApi, napi_value moduleNameNApi); Drawing::Typeface* GetFontFileProperties(const std::string path, const std::string familyName); bool AddTypefaceInformation(Drawing::Typeface* typeface, const std::string familyName); std::shared_ptr m_fontCollection = nullptr; diff --git a/interfaces/kits/napi/graphic/text/js_text_utils.cpp b/interfaces/kits/napi/graphic/text/js_text_utils.cpp index 8061e59634..f0d78f2824 100755 --- a/interfaces/kits/napi/graphic/text/js_text_utils.cpp +++ b/interfaces/kits/napi/graphic/text/js_text_utils.cpp @@ -252,4 +252,13 @@ bool GetPlaceholderSpanFromJS(napi_env env, napi_value argValue, PlaceholderSpan return true; } +size_t GetParamLen(napi_env env, napi_value param) +{ + size_t buffSize = 0; + napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &buffSize); + if (status != napi_ok || buffSize == 0) { + return 0; + } + return buffSize; +} } // namespace OHOS::Rosen diff --git a/interfaces/kits/napi/graphic/text/js_text_utils.h b/interfaces/kits/napi/graphic/text/js_text_utils.h index 605f6c38fe..c36c5c0d37 100755 --- a/interfaces/kits/napi/graphic/text/js_text_utils.h +++ b/interfaces/kits/napi/graphic/text/js_text_utils.h @@ -37,6 +37,28 @@ constexpr size_t ARGC_FOUR = 4; constexpr size_t ARGC_FIVE = 5; constexpr size_t ARGC_SIX = 6; +struct ResourceInfo { + int32_t resId = 0; + int32_t type = 0; + std::vector params; + std::string bundleName; + std::string moduleName; +}; + +enum class ResourceType { + COLOR = 10001, + FLOAT, + STRING, + PLURAL, + BOOLEAN, + INTARRAY, + INTEGER, + PATTERN, + STRARRAY, + MEDIA = 20000, + RAWFILE = 30000 +}; + enum class DrawingErrorCode : int32_t { OK = 0, ERROR_NO_PERMISSION = 201, // the value do not change. It is defined on all system @@ -344,5 +366,6 @@ bool GetParagraphStyleFromJS(napi_env env, napi_value argValue, TypographyStyle& bool GetPlaceholderSpanFromJS(napi_env env, napi_value argValue, PlaceholderSpan& placeholderSpan); +size_t GetParamLen(napi_env env, napi_value param); } // namespace OHOS::Rosen #endif // OHOS_JS_TEXT_UTILS_H \ No newline at end of file diff --git a/interfaces/kits/napi/graphic/webgl/include/context/webgl_rendering_context_base_impl.h b/interfaces/kits/napi/graphic/webgl/include/context/webgl_rendering_context_base_impl.h index c739793794..bacbe3d0fd 100644 --- a/interfaces/kits/napi/graphic/webgl/include/context/webgl_rendering_context_base_impl.h +++ b/interfaces/kits/napi/graphic/webgl/include/context/webgl_rendering_context_base_impl.h @@ -478,8 +478,9 @@ void WebGLRenderingContextBaseImpl::DeleteObject(napi_env env, uint64_t key) } napi_value obj; napi_status status = napi_get_reference_value(env, it->second, &obj); + auto ref = it->second; objects_[T::objectType].erase(it); - napi_delete_reference(env, it->second); + napi_delete_reference(env, ref); LOGD("DeleteObject %{public}u %{public}" PRIu64 " status %{public}u", T::objectType, key, status); } diff --git a/rosen/modules/2d_engine/rosen_text/adapter/skia_txt/convert.cpp b/rosen/modules/2d_engine/rosen_text/adapter/skia_txt/convert.cpp index 473c5155cd..1ae3553250 100644 --- a/rosen/modules/2d_engine/rosen_text/adapter/skia_txt/convert.cpp +++ b/rosen/modules/2d_engine/rosen_text/adapter/skia_txt/convert.cpp @@ -86,6 +86,7 @@ SPText::ParagraphStyle Convert(const TypographyStyle& style) .customSpTextStyle = style.customTextStyle, .textHeightBehavior = static_cast(style.textHeightBehavior), .hintingIsOn = style.hintingIsOn, + .breakStrategy = static_cast(style.breakStrategy), }; } @@ -117,7 +118,7 @@ void CopyTextStyleSymbol(const TextStyle& style, SPText::TextStyle& textStyle) textStyle.symbol.SetSymbolEffect(style.symbol.GetEffectStrategy()); textStyle.symbol.SetAnimationMode(style.symbol.GetAnimationMode()); textStyle.symbol.SetRepeatCount(style.symbol.GetRepeatCount()); - textStyle.symbol.SetAminationStart(style.symbol.GetAminationStart()); + textStyle.symbol.SetAnimationStart(style.symbol.GetAnimationStart()); textStyle.symbol.SetCommonSubType(style.symbol.GetCommonSubType()); for (auto [tag, value] : style.symbol.GetVisualMap()) { textStyle.fontFeatures.SetFeature(RemoveQuotes(tag), value); diff --git a/rosen/modules/2d_engine/rosen_text/export/rosen_text/hm_symbol_txt.h b/rosen/modules/2d_engine/rosen_text/export/rosen_text/hm_symbol_txt.h index 84ad12ce94..ee752935bc 100644 --- a/rosen/modules/2d_engine/rosen_text/export/rosen_text/hm_symbol_txt.h +++ b/rosen/modules/2d_engine/rosen_text/export/rosen_text/hm_symbol_txt.h @@ -125,9 +125,9 @@ public: repeatCount_ = repeatCount; } - void SetAminationStart(const bool aminationStart) + void SetAnimationStart(const bool animationStart) { - aminationStart_ = aminationStart; + animationStart_ = animationStart; } uint16_t GetAnimationMode() const @@ -140,9 +140,9 @@ public: return repeatCount_; } - bool GetAminationStart() const + bool GetAnimationStart() const { - return aminationStart_; + return animationStart_; } void SetVisualMode(const VisualMode visual) @@ -182,7 +182,7 @@ private: // variable_color : the 0 is the cumulative effect and 1 is the iteratuve effect. uint16_t animationMode_ = 1; int repeatCount_ = 1; - bool aminationStart_ = true; + bool animationStart_ = true; std::map visualMap_; Drawing::DrawingCommonSubType commonSubType_ = Drawing::DrawingCommonSubType::UP; }; diff --git a/rosen/modules/2d_engine/rosen_text/export/rosen_text/symbol_animation_config.h b/rosen/modules/2d_engine/rosen_text/export/rosen_text/symbol_animation_config.h index 426d27c055..e120048662 100644 --- a/rosen/modules/2d_engine/rosen_text/export/rosen_text/symbol_animation_config.h +++ b/rosen/modules/2d_engine/rosen_text/export/rosen_text/symbol_animation_config.h @@ -52,7 +52,7 @@ using SymbolAnimationConfig = struct SymbolAnimationConfig { uint64_t symbolSpanId = 0; uint16_t animationMode = 0; int repeatCount = 1; - bool aminationStart = false; + bool animationStart = true; Drawing::DrawingCommonSubType commonSubType = Drawing::DrawingCommonSubType::UP; }; } diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/impl/paragraph_builder_impl.cpp b/rosen/modules/2d_engine/rosen_text/skia_txt/impl/paragraph_builder_impl.cpp index 94fab726c6..894b20582a 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/impl/paragraph_builder_impl.cpp +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/impl/paragraph_builder_impl.cpp @@ -184,6 +184,7 @@ skt::ParagraphStyle ParagraphBuilderImpl::TextStyleToSkStyle(const ParagraphStyl strutStyle.setForceStrutHeight(txt.forceStrutHeight); strutStyle.setStrutEnabled(txt.strutEnabled); strutStyle.setWordBreakType(static_cast(txt.wordBreakType)); + strutStyle.setLineBreakStrategy(static_cast(txt.breakStrategy)); skStyle.setStrutStyle(strutStyle); skStyle.setTextAlign(static_cast(txt.textAlign)); @@ -281,7 +282,7 @@ void ParagraphBuilderImpl::CopyTextStylePaint(const TextStyle& txt, skia::textla paint.symbol.SetSymbolEffect(txt.symbol.GetEffectStrategy()); paint.symbol.SetAnimationMode(txt.symbol.GetAnimationMode()); paint.symbol.SetRepeatCount(txt.symbol.GetRepeatCount()); - paint.symbol.SetAminationStart(txt.symbol.GetAminationStart()); + paint.symbol.SetAnimationStart(txt.symbol.GetAnimationStart()); paint.symbol.SetCommonSubType(txt.symbol.GetCommonSubType()); skStyle.setForegroundPaintID(AllocPaintID(paint)); } diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.cpp b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.cpp index 70f0eccf52..d9a06f8a16 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.cpp +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.cpp @@ -136,7 +136,7 @@ bool SymbolNodeBuild::DecomposeSymbolAndDraw() } symbolAnimationConfig->repeatCount = repeatCount_; symbolAnimationConfig->animationMode = animationMode_; - symbolAnimationConfig->aminationStart = aminationStart_; + symbolAnimationConfig->animationStart = animationStart_; symbolAnimationConfig->symbolSpanId = symblSpanId_; symbolAnimationConfig->commonSubType = commonSubType_; animationFunc_(symbolAnimationConfig); diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.h b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.h index 498fb57acc..dfb84bcf56 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.h +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_node_build.h @@ -66,9 +66,9 @@ public: repeatCount_ = repeatCount; } - void SetAminationStart(const bool aminationStart) + void SetAnimationStart(const bool animationStart) { - aminationStart_ = aminationStart; + animationStart_ = animationStart; } void SetCommonSubType(Drawing::DrawingCommonSubType commonSubType) @@ -84,7 +84,7 @@ private: double offsetY_; uint16_t animationMode_ = 0; int repeatCount_ = 1; - bool aminationStart_ = false; + bool animationStart_ = true; Drawing::DrawingCommonSubType commonSubType_ = Drawing::DrawingCommonSubType::UP; std::function&)> diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_run.cpp b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_run.cpp index d479fb7b18..62e0326656 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_run.cpp +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_run.cpp @@ -127,7 +127,7 @@ void HMSymbolRun::DrawSymbol(RSCanvas* canvas, RSTextBlob* blob, const RSPoint& RSEffectStrategy symbolEffect = symbolTxt.GetEffectStrategy(); uint32_t symbolId = static_cast(glyphId); std::pair offsetXY(offset.GetX(), offset.GetY()); - if (symbolEffect > 0) { // 0 > has animation + if (symbolEffect > 0 && symbolTxt.GetAnimationStart()) { // 0 > has animation if (!SymbolAnimation(symbolData, symbolId, offsetXY, symbolTxt)) { ClearSymbolAnimation(symbolData, symbolId, offsetXY); canvas->DrawSymbol(symbolData, offset); @@ -160,7 +160,7 @@ bool HMSymbolRun::SymbolAnimation(const RSHMSymbolData symbol, const uint32_t gl symbolNode.SetSymbolId(symbolId_); symbolNode.SetAnimationMode(animationMode); symbolNode.SetRepeatCount(symbolTxt.GetRepeatCount()); - symbolNode.SetAminationStart(symbolTxt.GetAminationStart()); + symbolNode.SetAnimationStart(symbolTxt.GetAnimationStart()); symbolNode.SetCommonSubType(symbolTxt.GetCommonSubType()); if (!symbolNode.DecomposeSymbolAndDraw()) { return false; diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_txt.h b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_txt.h index a4fc6c5f29..cdafb3d96a 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_txt.h +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/symbol_engine/hm_symbol_txt.h @@ -77,9 +77,9 @@ public: repeatCount_ = repeatCount; } - void SetAminationStart(const bool aminationStart) + void SetAnimationStart(const bool animationStart) { - aminationStart_ = aminationStart; + animationStart_ = animationStart; } uint16_t GetAnimationMode() const @@ -92,9 +92,9 @@ public: return repeatCount_; } - bool GetAminationStart() const + bool GetAnimationStart() const { - return aminationStart_; + return animationStart_; } void SetCommonSubType(Drawing::DrawingCommonSubType commonSubType) @@ -113,7 +113,7 @@ private: RSEffectStrategy effectStrategy_ = RSEffectStrategy::NONE; uint16_t animationMode_ = 0; int repeatCount_ = 1; - bool aminationStart_ = false; + bool animationStart_ = true; Drawing::DrawingCommonSubType commonSubType_ = Drawing::DrawingCommonSubType::UP; }; } diff --git a/rosen/modules/2d_engine/rosen_text/skia_txt/txt/paragraph_style.h b/rosen/modules/2d_engine/rosen_text/skia_txt/txt/paragraph_style.h index c68ecb8b7c..58a94ee12c 100644 --- a/rosen/modules/2d_engine/rosen_text/skia_txt/txt/paragraph_style.h +++ b/rosen/modules/2d_engine/rosen_text/skia_txt/txt/paragraph_style.h @@ -31,6 +31,12 @@ enum class WordBreakType { BREAK_WORD, // break only occur after word. }; +enum class BreakStrategy { + GREEDY = 0, + HIGH_QUALITY = 1, + BALANCED = 2 +}; + class ParagraphStyle { public: TextStyle ConvertToTextStyle() const; @@ -68,6 +74,7 @@ public: bool customSpTextStyle = false; TextHeightBehavior textHeightBehavior = TextHeightBehavior::ALL; bool hintingIsOn = false; + BreakStrategy breakStrategy = BreakStrategy::GREEDY; }; } // namespace SPText } // namespace Rosen diff --git a/rosen/modules/2d_graphics/include/effect/image_filter.h b/rosen/modules/2d_graphics/include/effect/image_filter.h index cd0230e946..15eeb30a5d 100644 --- a/rosen/modules/2d_graphics/include/effect/image_filter.h +++ b/rosen/modules/2d_graphics/include/effect/image_filter.h @@ -114,7 +114,11 @@ public: * @param shader The shader that fills the result image * @return A shared pointer to ImageFilter that its type is shader. */ - static std::shared_ptr CreateShaderImageFilter(std::shared_ptr shader); + static std::shared_ptr CreateShaderImageFilter(std::shared_ptr shader, + const Rect& rect = { + -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), + std::numeric_limits::infinity(), std::numeric_limits::infinity() + }); virtual ~ImageFilter() = default; FilterType GetType() const; @@ -144,7 +148,7 @@ public: void InitWithColorBlur(const ColorFilter& cf, scalar x, scalar y, ImageBlurType blurType); ImageFilter(FilterType t, BlendMode mode, std::shared_ptr background, std::shared_ptr foreground = nullptr) noexcept; - ImageFilter(FilterType t, std::shared_ptr shader) noexcept; + ImageFilter(FilterType t, std::shared_ptr shader, const Rect& rect) noexcept; protected: ImageFilter() noexcept; diff --git a/rosen/modules/2d_graphics/include/recording/mask_cmd_list.h b/rosen/modules/2d_graphics/include/recording/mask_cmd_list.h index 593a852279..4f1b80600b 100644 --- a/rosen/modules/2d_graphics/include/recording/mask_cmd_list.h +++ b/rosen/modules/2d_graphics/include/recording/mask_cmd_list.h @@ -25,6 +25,35 @@ namespace OHOS { namespace Rosen { namespace Drawing { + + +/* OpItem */ +/** + * @brief Helper class for mask playback. + * Contains the playback context and a static mapping table: { OpItemType, OpItemPlaybackFunc }. + */ +class MaskPlayer { +public: + MaskPlayer(std::shared_ptr& path, Brush& brush, const CmdList& cmdList); + MaskPlayer(std::shared_ptr& path, Brush& brush, Pen& pen, const CmdList& cmdList); + ~MaskPlayer() = default; + + /** + * @brief Obtain the corresponding func according to the type lookup mapping table + * and then invoke the func to plays opItem back to mask which in context. + */ + bool Playback(uint32_t type, const void* opItem, size_t leftOpAllocatorSize); + + std::shared_ptr& path_; + Brush& brush_; + Pen& pen_; + const CmdList& cmdList_; + + using MaskPlaybackFunc = void(*)(MaskPlayer& palyer, const void* opItem, size_t leftOpAllocatorSize); +private: + static std::unordered_map opPlaybackFuncLUT_; +}; + class DRAWING_API MaskCmdList : public CmdList { public: MaskCmdList() = default; @@ -48,33 +77,9 @@ public: bool Playback(std::shared_ptr& path, Brush& brush) const; bool Playback(std::shared_ptr& path, Pen& pen, Brush& brush) const; -}; -/* OpItem */ -/** - * @brief Helper class for mask playback. - * Contains the playback context and a static mapping table: { OpItemType, OpItemPlaybackFunc }. - */ -class MaskPlayer { -public: - MaskPlayer(std::shared_ptr& path, Brush& brush, const CmdList& cmdList); - MaskPlayer(std::shared_ptr& path, Brush& brush, Pen& pen, const CmdList& cmdList); - ~MaskPlayer() = default; - - /** - * @brief Obtain the corresponding func according to the type lookup mapping table - * and then invoke the func to plays opItem back to mask which in context. - */ - bool Playback(uint32_t type, const void* opItem); - - std::shared_ptr& path_; - Brush& brush_; - Pen& pen_; - const CmdList& cmdList_; - - using MaskPlaybackFunc = void(*)(MaskPlayer& palyer, const void* opItem); private: - static std::unordered_map opPlaybackFuncLUT_; + bool Playback(MaskPlayer &player) const; }; class MaskOpItem : public OpItem { @@ -95,7 +100,7 @@ public: explicit MaskBrushOpItem(const BrushHandle& brushHandle); ~MaskBrushOpItem() = default; - static void Playback(MaskPlayer& player, const void* opItem); + static void Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize); void Playback(Brush& brush, const CmdList& cmdList) const; private: @@ -107,7 +112,7 @@ public: explicit MaskPenOpItem(const PenHandle& penHandle); ~MaskPenOpItem() = default; - static void Playback(MaskPlayer& player, const void* opItem); + static void Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize); void Playback(Pen& pen, const CmdList& cmdList) const; private: @@ -119,7 +124,7 @@ public: explicit MaskPathOpItem(const OpDataHandle& pathHandle); ~MaskPathOpItem() = default; - static void Playback(MaskPlayer& player, const void* opItem); + static void Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize); void Playback(std::shared_ptr& path, const CmdList& cmdList) const; private: diff --git a/rosen/modules/2d_graphics/include/utils/region.h b/rosen/modules/2d_graphics/include/utils/region.h index ce18b98a56..e991fc3248 100644 --- a/rosen/modules/2d_graphics/include/utils/region.h +++ b/rosen/modules/2d_graphics/include/utils/region.h @@ -37,6 +37,11 @@ public: Region& operator=(const Region& other); virtual ~Region() = default; + void Clone(const Region& other) + { + impl_->Clone(other); + } + virtual DrawingType GetDrawingType() const { return DrawingType::COMMON; diff --git a/rosen/modules/2d_graphics/src/drawing/effect/image_filter.cpp b/rosen/modules/2d_graphics/src/drawing/effect/image_filter.cpp index 500184c290..b26b368cc0 100644 --- a/rosen/modules/2d_graphics/src/drawing/effect/image_filter.cpp +++ b/rosen/modules/2d_graphics/src/drawing/effect/image_filter.cpp @@ -162,16 +162,16 @@ ImageFilter::ImageFilter(FilterType t, BlendMode mode, std::shared_ptr ImageFilter::CreateShaderImageFilter( - std::shared_ptr shader) + std::shared_ptr shader, const Rect& rect) { - return std::make_shared(ImageFilter::FilterType::SHADER, shader); + return std::make_shared(ImageFilter::FilterType::SHADER, shader, rect); } -ImageFilter::ImageFilter(FilterType t, std::shared_ptr shader) noexcept +ImageFilter::ImageFilter(FilterType t, std::shared_ptr shader, const Rect& rect) noexcept : ImageFilter() { type_ = t; - impl_->InitWithShader(shader); + impl_->InitWithShader(shader, rect); } } // namespace Drawing diff --git a/rosen/modules/2d_graphics/src/drawing/engine_adapter/impl_interface/image_filter_impl.h b/rosen/modules/2d_graphics/src/drawing/engine_adapter/impl_interface/image_filter_impl.h index cb24a789a1..5585288541 100644 --- a/rosen/modules/2d_graphics/src/drawing/engine_adapter/impl_interface/image_filter_impl.h +++ b/rosen/modules/2d_graphics/src/drawing/engine_adapter/impl_interface/image_filter_impl.h @@ -72,7 +72,7 @@ public: virtual bool Deserialize(std::shared_ptr data) = 0; virtual void InitWithBlend(BlendMode mode, std::shared_ptr background, std::shared_ptr foreground = nullptr) = 0; - virtual void InitWithShader(std::shared_ptr shader) = 0; + virtual void InitWithShader(std::shared_ptr shader, const Rect& rect) = 0; }; } // namespace Drawing } // namespace Rosen diff --git a/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.cpp b/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.cpp index 72cf822047..e2964b329e 100644 --- a/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.cpp +++ b/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.cpp @@ -191,13 +191,15 @@ void SkiaImageFilter::InitWithBlend(BlendMode mode, std::shared_ptr filter_ = SkImageFilters::Blend(static_cast(mode), outer, inner); } -void SkiaImageFilter::InitWithShader(std::shared_ptr shader) +void SkiaImageFilter::InitWithShader(std::shared_ptr shader, const Rect& rect) { sk_sp skShader = nullptr; if (shader != nullptr && shader->GetImpl() != nullptr) { skShader = shader->GetImpl()->GetShader(); } - filter_ = SkImageFilters::Shader(skShader); + SkRect skiaRect = {rect.left_, rect.top_, rect.right_, rect.bottom_}; + SkImageFilters::CropRect skCropRect(skiaRect); + filter_ = SkImageFilters::Shader(skShader, skCropRect); } } // namespace Drawing diff --git a/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.h b/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.h index 5b740d2058..c53f6fc5b5 100644 --- a/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.h +++ b/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_image_filter.h @@ -50,7 +50,7 @@ public: const std::shared_ptr f) override; void InitWithBlend(BlendMode mode, std::shared_ptr background, std::shared_ptr foreground = nullptr) override; - void InitWithShader(std::shared_ptr shader) override; + void InitWithShader(std::shared_ptr shader, const Rect& rect) override; sk_sp GetImageFilter() const; /* * @brief Update the member variable to filter, adaptation layer calls. diff --git a/rosen/modules/2d_graphics/src/drawing/recording/draw_cmd_list.cpp b/rosen/modules/2d_graphics/src/drawing/recording/draw_cmd_list.cpp index c01ee899e2..6c5038e4c7 100644 --- a/rosen/modules/2d_graphics/src/drawing/recording/draw_cmd_list.cpp +++ b/rosen/modules/2d_graphics/src/drawing/recording/draw_cmd_list.cpp @@ -189,7 +189,7 @@ std::string DrawCmdList::GetOpsWithDesc() const desc += typeOpDes[item->GetType()]; desc += "\n"; } - LOGI("DrawCmdList::GetOpsWithDesc %{public}s, opitem sz: %{public}zu", desc.c_str(), drawOpItems_.size()); + LOGD("DrawCmdList::GetOpsWithDesc %{public}s, opitem sz: %{public}zu", desc.c_str(), drawOpItems_.size()); return desc; } diff --git a/rosen/modules/2d_graphics/src/drawing/recording/mask_cmd_list.cpp b/rosen/modules/2d_graphics/src/drawing/recording/mask_cmd_list.cpp index 487ec45d31..8c8181a551 100644 --- a/rosen/modules/2d_graphics/src/drawing/recording/mask_cmd_list.cpp +++ b/rosen/modules/2d_graphics/src/drawing/recording/mask_cmd_list.cpp @@ -36,15 +36,19 @@ std::shared_ptr MaskCmdList::CreateFromData(const CmdListData& data return cmdList; } -bool MaskCmdList::Playback(std::shared_ptr& path, Brush& brush) const +bool MaskCmdList::Playback(MaskPlayer &player) const { uint32_t offset = 0; - MaskPlayer player(path, brush, *this); + size_t totalSize = opAllocator_.GetSize(); do { + if (totalSize < offset || totalSize - offset < sizeof(OpItem)) { + LOGD("MaskCmdList::Playback size error"); + return false; + } void* itemPtr = opAllocator_.OffsetToAddr(offset); OpItem* curOpItemPtr = static_cast(itemPtr); if (curOpItemPtr != nullptr) { - if (!player.Playback(curOpItemPtr->GetType(), itemPtr)) { + if (!player.Playback(curOpItemPtr->GetType(), itemPtr, totalSize - offset)) { LOGD("MaskCmdList::Playback failed!"); break; } @@ -59,27 +63,16 @@ bool MaskCmdList::Playback(std::shared_ptr& path, Brush& brush) const return true; } +bool MaskCmdList::Playback(std::shared_ptr& path, Brush& brush) const +{ + MaskPlayer player(path, brush, *this); + return Playback(player); +} + bool MaskCmdList::Playback(std::shared_ptr& path, Pen& pen, Brush& brush) const { - uint32_t offset = 0; MaskPlayer player(path, brush, pen, *this); - do { - void* itemPtr = opAllocator_.OffsetToAddr(offset); - OpItem* curOpItemPtr = static_cast(itemPtr); - if (curOpItemPtr != nullptr) { - if (!player.Playback(curOpItemPtr->GetType(), itemPtr)) { - LOGE("MaskCmdList::Playback failed!"); - break; - } - - offset = curOpItemPtr->GetNextOpItemOffset(); - } else { - LOGE("MaskCmdList::Playback failed, opItem is nullptr"); - break; - } - } while (offset != 0); - - return true; + return Playback(player); } /* OpItem */ @@ -95,7 +88,7 @@ MaskPlayer::MaskPlayer(std::shared_ptr& path, Brush& brush, const CmdList& MaskPlayer::MaskPlayer(std::shared_ptr& path, Brush& brush, Pen& pen, const CmdList& cmdList) : path_(path), brush_(brush), pen_(pen), cmdList_(cmdList) {} -bool MaskPlayer::Playback(uint32_t type, const void* opItem) +bool MaskPlayer::Playback(uint32_t type, const void* opItem, size_t leftOpAllocatorSize) { if (type == MaskOpItem::OPITEM_HEAD) { return true; @@ -107,7 +100,7 @@ bool MaskPlayer::Playback(uint32_t type, const void* opItem) } auto func = it->second; - (*func)(*this, opItem); + (*func)(*this, opItem, leftOpAllocatorSize); return true; } @@ -115,9 +108,9 @@ bool MaskPlayer::Playback(uint32_t type, const void* opItem) MaskBrushOpItem::MaskBrushOpItem(const BrushHandle& brushHandle) : MaskOpItem(MASK_BRUSH_OPITEM), brushHandle_(brushHandle) {} -void MaskBrushOpItem::Playback(MaskPlayer& player, const void* opItem) +void MaskBrushOpItem::Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize) { - if (opItem != nullptr) { + if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskBrushOpItem)) { const auto* op = static_cast(opItem); op->Playback(player.brush_, player.cmdList_); } @@ -155,9 +148,9 @@ void MaskBrushOpItem::Playback(Brush& brush, const CmdList& cmdList) const MaskPathOpItem::MaskPathOpItem(const OpDataHandle& pathHandle) : MaskOpItem(MASK_PATH_OPITEM), pathHandle_(pathHandle) {} -void MaskPathOpItem::Playback(MaskPlayer& player, const void* opItem) +void MaskPathOpItem::Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize) { - if (opItem != nullptr) { + if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskPathOpItem)) { const auto* op = static_cast(opItem); op->Playback(player.path_, player.cmdList_); } @@ -172,9 +165,9 @@ void MaskPathOpItem::Playback(std::shared_ptr& path, const CmdList& cmdLis MaskPenOpItem::MaskPenOpItem(const PenHandle& penHandle) : MaskOpItem(MASK_PEN_OPITEM), penHandle_(penHandle) {} -void MaskPenOpItem::Playback(MaskPlayer &player, const void *opItem) +void MaskPenOpItem::Playback(MaskPlayer &player, const void *opItem, size_t leftOpAllocatorSize) { - if (opItem != nullptr) { + if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskPenOpItem)) { const auto* op = static_cast(opItem); op->Playback(player.pen_, player.cmdList_); } diff --git a/rosen/modules/composer/hdi_backend/include/hdi_device.h b/rosen/modules/composer/hdi_backend/include/hdi_device.h index 9db3122045..5251725384 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_device.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_device.h @@ -62,7 +62,7 @@ public: virtual int32_t GetSupportedMetaDataKey(uint32_t screenId, std::vector &keys) = 0; virtual int32_t Commit(uint32_t screenId, sptr &fence) = 0; virtual int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr &fence, int32_t &skipState, - bool &needFlush) = 0; + bool &needFlush, std::vector& layers, std::vector>& fences) = 0; /* set & get device screen info end */ /* set & get device layer info begin */ diff --git a/rosen/modules/composer/hdi_backend/include/hdi_device_impl.h b/rosen/modules/composer/hdi_backend/include/hdi_device_impl.h index 8429985ae2..c22ad214be 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_device_impl.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_device_impl.h @@ -60,8 +60,8 @@ public: int32_t GetHDRCapabilityInfos(uint32_t screenId, GraphicHDRCapability &info) override; int32_t GetSupportedMetaDataKey(uint32_t screenId, std::vector &keys) override; int32_t Commit(uint32_t screenId, sptr &fence) override; - int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr &fence, int32_t &skipState, - bool &needFlush) override; + int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr &fence, int32_t &skipState, bool &needFlush, + std::vector& layers, std::vector>& fences) override; /* set & get device screen info end */ /* set & get device layer info begin */ diff --git a/rosen/modules/composer/hdi_backend/include/hdi_output.h b/rosen/modules/composer/hdi_backend/include/hdi_output.h index 7d1003ba19..303bf9e64d 100644 --- a/rosen/modules/composer/hdi_backend/include/hdi_output.h +++ b/rosen/modules/composer/hdi_backend/include/hdi_output.h @@ -86,7 +86,8 @@ public: int32_t FlushScreen(std::vector &compClientLayers); int32_t SetScreenClientInfo(const FrameBufferEntry &fbEntry); int32_t Commit(sptr &fbFence); - int32_t CommitAndGetReleaseFence(sptr &fbFence, int32_t &skipState, bool &needFlush); + int32_t CommitAndGetReleaseFence(sptr &fbFence, int32_t &skipState, bool &needFlush, + std::vector& layers, std::vector>& fences); int32_t UpdateInfosAfterCommit(sptr fbFence); int32_t ReleaseFramebuffer(const sptr& releaseFence); std::map> GetLayersReleaseFence(); @@ -121,6 +122,9 @@ private: uint32_t bufferCacheCountMax_ = 0; std::mutex layerMutex_; + std::vector layersId_; + std::vector> fences_; + int32_t CreateLayer(uint64_t surfaceId, const LayerInfoPtr &layerInfo); void DeletePrevLayers(); void ResetLayerStatus(); diff --git a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp index 81afdb8afb..b0e543f8e0 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp @@ -129,13 +129,15 @@ void HdiBackend::Repaint(const OutputPtr &output) bool needFlush = false; int32_t skipState = INT32_MAX; + std::vector layers; + std::vector> fences; int32_t ret = output->PreProcessLayersComp(); if (ret != GRAPHIC_DISPLAY_SUCCESS) { return; } sptr fbFence = SyncFence::INVALID_FENCE; - ret = output->CommitAndGetReleaseFence(fbFence, skipState, needFlush); + ret = output->CommitAndGetReleaseFence(fbFence, skipState, needFlush, layers, fences); if (ret != GRAPHIC_DISPLAY_SUCCESS) { HLOGE("first commit failed, ret is %{public}d, skipState is %{public}d", ret, skipState); } diff --git a/rosen/modules/composer/hdi_backend/src/hdi_device_impl.cpp b/rosen/modules/composer/hdi_backend/src/hdi_device_impl.cpp index 492434e8d4..3ca8eca4cb 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_device_impl.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_device_impl.cpp @@ -399,18 +399,31 @@ int32_t HdiDeviceImpl::Commit(uint32_t screenId, sptr &fence) return ret; } -int32_t HdiDeviceImpl::CommitAndGetReleaseFence(uint32_t screenId, sptr &fence, int32_t &skipState, - bool &needFlush) +int32_t HdiDeviceImpl::CommitAndGetReleaseFence(uint32_t screenId, sptr &fence, + int32_t &skipState, bool &needFlush, std::vector& layers, std::vector>& fences) { ScopedBytrace bytrace(__func__); CHECK_FUNC(g_composer); int32_t fenceFd = -1; - int32_t ret = g_composer->CommitAndGetReleaseFence(screenId, fenceFd, skipState, needFlush); + std::vectorfenceFds; + + int32_t ret = g_composer->CommitAndGetReleaseFence(screenId, fenceFd, skipState, needFlush, layers, fenceFds); - if (skipState == 0) { + if (skipState == 0 || fenceFd >= 0) { fence = new SyncFence(fenceFd); + } else { + fence =new SyncFence(-1); } + size_t fencesNum = fenceFds.size(); + fences.resize(fencesNum); + for (size_t i = 0; i < fencesNum; i++) { + if (fenceFds[i] >= 0) { + fences[i] = new SyncFence(fenceFds[i]); + } else { + fences[i] = new SyncFence(-1); + } + } return ret; } /* set & get device screen info end */ diff --git a/rosen/modules/composer/hdi_backend/src/hdi_output.cpp b/rosen/modules/composer/hdi_backend/src/hdi_output.cpp index 77b515faa9..dc64826af0 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_output.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_output.cpp @@ -529,10 +529,13 @@ int32_t HdiOutput::Commit(sptr &fbFence) return device_->Commit(screenId_, fbFence); } -int32_t HdiOutput::CommitAndGetReleaseFence(sptr &fbFence, int32_t& skipState, bool& needFlush) +int32_t HdiOutput::CommitAndGetReleaseFence(sptr &fbFence, int32_t& skipState, bool& needFlush, + std::vector& layers, std::vector>& fences) { CHECK_DEVICE_NULL(device_); - return device_->CommitAndGetReleaseFence(screenId_, fbFence, skipState, needFlush); + layersId_.clear(); + fences_.clear(); + return device_->CommitAndGetReleaseFence(screenId_, fbFence, skipState, needFlush, layers, fences); } int32_t HdiOutput::UpdateInfosAfterCommit(sptr fbFence) @@ -676,30 +679,18 @@ void HdiOutput::ReleaseLayers(sptr& releaseFence) std::map> HdiOutput::GetLayersReleaseFence() { - if (device_ == nullptr) { - return {}; - } - std::vector layersId; - std::vector> fences; - int32_t ret = device_->GetScreenReleaseFence(screenId_, layersId, fences); - if (ret != GRAPHIC_DISPLAY_SUCCESS || layersId.size() != fences.size()) { - HLOGE("GetScreenReleaseFence failed, ret is %{public}d, layerId size[%{public}d], fence size[%{public}d]", - ret, (int)layersId.size(), (int)fences.size()); - return {}; - } - std::map> res; std::unique_lock lock(layerMutex_); - size_t layerNum = layersId.size(); + size_t layerNum = layersId_.size(); for (size_t i = 0; i < layerNum; i++) { - auto iter = layerIdMap_.find(layersId[i]); + auto iter = layerIdMap_.find(layersId_[i]); if (iter == layerIdMap_.end()) { - HLOGE("Invalid hdi layer id [%{public}u]", layersId[i]); + HLOGE("Invalid hdi layer id [%{public}u]", layersId_[i]); continue; } const LayerPtr &layer = iter->second; - layer->MergeWithLayerFence(fences[i]); + layer->MergeWithLayerFence(fences_[i]); res[layer->GetLayerInfo()] = layer->GetReleaseFence(); } return res; diff --git a/rosen/modules/composer/hdi_backend/test/systemtest/mock_hdi_device_systest.h b/rosen/modules/composer/hdi_backend/test/systemtest/mock_hdi_device_systest.h index dab1a9bf9f..ffcef8f0aa 100644 --- a/rosen/modules/composer/hdi_backend/test/systemtest/mock_hdi_device_systest.h +++ b/rosen/modules/composer/hdi_backend/test/systemtest/mock_hdi_device_systest.h @@ -92,7 +92,8 @@ public: MOCK_METHOD4(CreateLayer, int32_t(uint32_t, const GraphicLayerInfo&, uint32_t, uint32_t&)); MOCK_METHOD2(CloseLayer, int32_t(uint32_t, uint32_t)); - MOCK_METHOD4(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&)); + MOCK_METHOD6(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&, + std::vector&, std::vector>&)); MOCK_METHOD0(Destroy, void()); }; } // namespace MockSys diff --git a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp index b8289e5240..7b196175a1 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp +++ b/rosen/modules/composer/hdi_backend/test/unittest/hdioutput_test.cpp @@ -265,11 +265,13 @@ HWTEST_F(HdiOutputTest, ClearFrameBuffer002, Function | MediumTest | Level1) */ HWTEST_F(HdiOutputTest, CommitAndGetReleaseFence001, Function | MediumTest| Level1) { - EXPECT_CALL(*hdiDeviceMock_, CommitAndGetReleaseFence(_, _, _, _)).WillRepeatedly(testing::Return(0)); + EXPECT_CALL(*hdiDeviceMock_, CommitAndGetReleaseFence(_, _, _, _, _, _)).WillRepeatedly(testing::Return(0)); sptr fbFence = SyncFence::INVALID_FENCE; int32_t skipState = 0; bool needFlush = false; - ASSERT_EQ(HdiOutputTest::hdiOutput_->CommitAndGetReleaseFence(fbFence, skipState, needFlush), + std::vector layers; + std::vector> fences; + ASSERT_EQ(HdiOutputTest::hdiOutput_->CommitAndGetReleaseFence(fbFence, skipState, needFlush, layers, fences), GRAPHIC_DISPLAY_SUCCESS); } } // namespace diff --git a/rosen/modules/composer/hdi_backend/test/unittest/mock_hdi_device.h b/rosen/modules/composer/hdi_backend/test/unittest/mock_hdi_device.h index a36a3697d4..d04a5997bd 100644 --- a/rosen/modules/composer/hdi_backend/test/unittest/mock_hdi_device.h +++ b/rosen/modules/composer/hdi_backend/test/unittest/mock_hdi_device.h @@ -91,7 +91,8 @@ public: MOCK_METHOD4(CreateLayer, int32_t(uint32_t, const GraphicLayerInfo&, uint32_t, uint32_t&)); MOCK_METHOD2(CloseLayer, int32_t(uint32_t, uint32_t)); - MOCK_METHOD4(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&)); + MOCK_METHOD6(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&, + std::vector&, std::vector>&)); MOCK_METHOD0(Destroy, void()); }; } // namespace Mock diff --git a/rosen/modules/composer/vsync/include/vsync_distributor.h b/rosen/modules/composer/vsync/include/vsync_distributor.h index cff1c5ea88..afe4253767 100644 --- a/rosen/modules/composer/vsync/include/vsync_distributor.h +++ b/rosen/modules/composer/vsync/include/vsync_distributor.h @@ -152,6 +152,7 @@ private: #ifdef COMPOSER_SCHED_ENABLE void SubScribeSystemAbility(const std::string& threadName); #endif + void NotifyMainThread(); sptr saStatusChangeListener_ = nullptr; std::thread threadLoop_; diff --git a/rosen/modules/composer/vsync/src/vsync_distributor.cpp b/rosen/modules/composer/vsync/src/vsync_distributor.cpp index 2c5f7c31eb..3b13e51342 100644 --- a/rosen/modules/composer/vsync/src/vsync_distributor.cpp +++ b/rosen/modules/composer/vsync/src/vsync_distributor.cpp @@ -239,6 +239,7 @@ VSyncDistributor::~VSyncDistributor() #if defined(RS_ENABLE_DVSYNC) { std::unique_lock locker(mutex_); + dvsync_->MarkPendingRNVIsProcess(false); dvsync_->RNVNotify(); } #endif @@ -323,6 +324,7 @@ void VSyncDistributor::WaitForVsyncOrRequest(std::unique_lock &locke // before con_ wait, notify the rnv_con. #if defined(RS_ENABLE_DVSYNC) if (IsDVsyncOn()) { + dvsync_->MarkPendingRNVIsProcess(false); dvsync_->RNVNotify(); } #endif @@ -342,8 +344,8 @@ void VSyncDistributor::WaitForVsyncOrRequest(std::unique_lock &locke ScopedBytrace func(name_ + "_EnableVsync"); EnableVSync(); } - lockExecute_ = true; } + pendingRNVInDVsync_ = false; } #endif } @@ -390,6 +392,7 @@ void VSyncDistributor::ThreadMain() EnableVSync(); #if defined(RS_ENABLE_DVSYNC) if (IsDVsyncOn()) { + dvsync_->MarkPendingRNVIsProcess(false); dvsync_->RNVNotify(); } #endif @@ -446,7 +449,7 @@ void VSyncDistributor::ThreadMain() { std::unique_lock locker(mutex_); pendingRNVInVsync_ = false; - pendingRNVInDVsync_ = false; + lockExecute_ = true; } #endif PostVSyncEvent(conns, timestamp); @@ -477,9 +480,9 @@ void VSyncDistributor::OnVSyncEvent(int64_t now, int64_t period, uint32_t refres dvsync_->RuntimeSwitch(); #endif if (IsDVsyncOn()) { - ScopedBytrace func("VSyncD onVSyncEvent, now" + std::to_string(now)); + ScopedBytrace func("VSyncD onVSyncEvent, now:" + std::to_string(now)); } else { - ScopedBytrace func("VSync onVSyncEvent, now" + std::to_string(now)); + ScopedBytrace func("VSync onVSyncEvent, now:" + std::to_string(now)); } #if defined(RS_ENABLE_DVSYNC) @@ -658,6 +661,13 @@ VsyncError VSyncDistributor::RequestNextVSync(const sptr &conne VLOGE("connection is nullptr"); return VSYNC_ERROR_NULLPTR; } + +#if defined(RS_ENABLE_DVSYNC) + if (IsDVsyncOn() && fromWhom == "ltpoForceUpdate") { + return VSYNC_ERROR_OK; + } +#endif + ScopedBytrace func(connection->info_.name_ + "_RequestNextVSync"); std::unique_lock locker(mutex_); @@ -689,11 +699,19 @@ VsyncError VSyncDistributor::RequestNextVSync(const sptr &conne connection->rate_ = 0; } connection->triggerThisTime_ = true; + NotifyMainThread(); + VLOGD("conn name:%{public}s, rate:%{public}d", connection->info_.name_.c_str(), connection->rate_); + return VSYNC_ERROR_OK; +} + +void VSyncDistributor::NotifyMainThread() +{ #if defined(RS_ENABLE_DVSYNC) if (IsDVsyncOn()) { if (!lockExecute_) { con_.notify_all(); } else { + ScopedBytrace func("set pendingRNVInDVsync_ = true"); pendingRNVInDVsync_ = true; dvsync_->RNVNotify(); } @@ -703,8 +721,6 @@ VsyncError VSyncDistributor::RequestNextVSync(const sptr &conne #else con_.notify_all(); #endif - VLOGD("conn name:%{public}s, rate:%{public}d", connection->info_.name_.c_str(), connection->rate_); - return VSYNC_ERROR_OK; } VsyncError VSyncDistributor::SetVSyncRate(int32_t rate, const sptr& connection) @@ -888,6 +904,7 @@ void VSyncDistributor::SetFrameIsRender(bool isRender) lockExecute_ = false; if (IsDVsyncOn() && pendingRNVInDVsync_) { ScopedBytrace func("pendingRNVInDVsync_ is true, notify"); + dvsync_->MarkPendingRNVIsProcess(true); con_.notify_all(); } #endif diff --git a/rosen/modules/composer/vsync/src/vsync_receiver.cpp b/rosen/modules/composer/vsync/src/vsync_receiver.cpp index d4893cb155..b309aecb76 100644 --- a/rosen/modules/composer/vsync/src/vsync_receiver.cpp +++ b/rosen/modules/composer/vsync/src/vsync_receiver.cpp @@ -61,6 +61,7 @@ void VSyncCallBackListener::OnReadable(int32_t fileDescriptor) { std::lock_guard locker(mtx_); cb = vsyncCallbacks_; + RNVFlag_ = false; } now = data[0]; period_ = data[1]; @@ -153,6 +154,7 @@ VsyncError VSyncReceiver::RequestNextVSync(FrameCallback callback, const std::st return VSYNC_ERROR_API_FAILED; } listener_->SetCallback(callback); + listener_->SetRNVFlag(true); ScopedDebugTrace func("VSyncReceiver::RequestNextVSync:" + name_); if (OHOS::Rosen::RsFrameReportExt::GetInstance().GetEnable()) { OHOS::Rosen::RsFrameReportExt::GetInstance().RequestNextVSync(); @@ -222,5 +224,14 @@ VsyncError VSyncReceiver::Destroy() } return connection_->Destroy(); } + +bool VSyncReceiver::IsRequestedNextVSync() +{ + std::lock_guard locker(initMutex_); + if (!init_) { + return false; + } + return listener_->GetRNVFlag(); +} } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/composer/vsync/test/unittest/vsync_receiver_test.cpp b/rosen/modules/composer/vsync/test/unittest/vsync_receiver_test.cpp index 5a5bbe88a1..058c63df2c 100644 --- a/rosen/modules/composer/vsync/test/unittest/vsync_receiver_test.cpp +++ b/rosen/modules/composer/vsync/test/unittest/vsync_receiver_test.cpp @@ -131,6 +131,18 @@ HWTEST_F(VsyncReceiverTest, Init003, Function | MediumTest| Level3) ASSERT_NE(ret, VSYNC_ERROR_OK); } +/* +* Function: IsRequestedNextVSync001 +* Type: Function +* Rank: Important(2) +* EnvConditions: N/A +* CaseDescription: 1. call IsRequestedNextVSync + */ +HWTEST_F(VsyncReceiverTest, IsRequestedNextVSync001, Function | MediumTest| Level3) +{ + ASSERT_EQ(VsyncReceiverTest::vsyncReceiver->IsRequestedNextVSync(), false); +} + /* * Function: RequestNextVSync001 * Type: Function @@ -167,6 +179,18 @@ HWTEST_F(VsyncReceiverTest, RequestNextVSync002, Function | MediumTest| Level3) vsyncDistributor->RemoveConnection(conn); } +/* +* Function: IsRequestedNextVSync002 +* Type: Function +* Rank: Important(2) +* EnvConditions: N/A +* CaseDescription: 1. call IsRequestedNextVSync + */ +HWTEST_F(VsyncReceiverTest, IsRequestedNextVSync002, Function | MediumTest| Level3) +{ + ASSERT_EQ(VsyncReceiverTest::vsyncReceiver->IsRequestedNextVSync(), true); +} + /* * Function: GetVSyncPeriodAndLastTimeStamp001 * Type: Function diff --git a/rosen/modules/create_pixelmap_surface/src/pixel_map_from_surface.cpp b/rosen/modules/create_pixelmap_surface/src/pixel_map_from_surface.cpp index a9395928b5..c95114517c 100644 --- a/rosen/modules/create_pixelmap_surface/src/pixel_map_from_surface.cpp +++ b/rosen/modules/create_pixelmap_surface/src/pixel_map_from_surface.cpp @@ -20,19 +20,19 @@ #endif #include "pixel_map_from_surface.h" -#include #include +#include +#include "common/rs_background_thread.h" +#include "image/image.h" #include "native_window.h" -#include "sync_fence.h" #include "platform/common/rs_log.h" #include "platform/common/rs_system_properties.h" -#include "image/image.h" #if defined(RS_ENABLE_VK) #include "platform/ohos/backend/native_buffer_utils.h" #endif -#include "common/rs_background_thread.h" -#include "surface_buffer.h" #include "skia_adapter/skia_gpu_context.h" +#include "surface_buffer.h" +#include "sync_fence.h" #if defined(RS_ENABLE_GL) #include "EGL/egl.h" @@ -63,6 +63,9 @@ static sptr LocalDmaMemAlloc(const uint32_t &width, const uint32_ RS_LOGE("Unsupport dma mem alloc"); return nullptr; #else + if (pixelmap == nullptr) { + return nullptr; + } sptr surfaceBuffer = SurfaceBuffer::Create(); BufferRequestConfig requestConfig = { .width = width, diff --git a/rosen/modules/effect/egl/BUILD.gn b/rosen/modules/effect/egl/BUILD.gn index b38b709102..68d6599606 100644 --- a/rosen/modules/effect/egl/BUILD.gn +++ b/rosen/modules/effect/egl/BUILD.gn @@ -23,6 +23,7 @@ ohos_shared_library("libegl_effect") { "//third_party/openGLES/api", "$graphic_2d_root/utils/log", "include", + "$graphic_2d_root/rosen/modules/effect/effectChain/include", ] cflags = [ diff --git a/rosen/modules/effect/egl/include/egl_manager.h b/rosen/modules/effect/egl/include/egl_manager.h index 5758ca9865..1c01e6b2cd 100644 --- a/rosen/modules/effect/egl/include/egl_manager.h +++ b/rosen/modules/effect/egl/include/egl_manager.h @@ -19,7 +19,7 @@ #include #include #include -#include "../../effectChain/include/ec_log.h" +#include "ec_log.h" #ifdef __cplusplus extern "C" { diff --git a/rosen/modules/render_service/BUILD.gn b/rosen/modules/render_service/BUILD.gn index c06a20a5fb..0f4bc21a06 100644 --- a/rosen/modules/render_service/BUILD.gn +++ b/rosen/modules/render_service/BUILD.gn @@ -32,7 +32,7 @@ ohos_shared_library("librender_service") { sanitize = { cfi = true cfi_cross_dso = true - cfi_no_nvcall = true + cfi_vcall_icall_only = true debug = false } if (enhanced_opt) { @@ -195,6 +195,7 @@ ohos_shared_library("librender_service") { "$graphic_2d_root/rosen/modules/hyper_graphic_manager/core/frame_rate_manager", "$graphic_2d_root/rosen/modules/hyper_graphic_manager/core/hgm_screen_manager", "$graphic_2d_root/rosen/modules/hyper_graphic_manager/core/utils", + "$graphic_2d_root/rosen/modules/create_pixelmap_surface/include", ] if (use_video_processing_engine) { include_dirs += [ "$video_processing_engine_root/interfaces/inner_api" ] @@ -209,6 +210,7 @@ ohos_shared_library("librender_service") { deps = [ "$graphic_2d_root/rosen/modules/composer:libcomposer", + "$graphic_2d_root/rosen/modules/create_pixelmap_surface:create_pixelmap_surface", "$graphic_2d_root/rosen/modules/hyper_graphic_manager:libhyper_graphic_manager", "$graphic_2d_root/rosen/modules/render_frame_trace:render_frame_trace", "$graphic_2d_root/rosen/modules/render_service_base:librender_service_base", @@ -386,7 +388,7 @@ ohos_executable("render_service") { sanitize = { cfi = true cfi_cross_dso = true - cfi_no_nvcall = true + cfi_vcall_icall_only = true debug = false if (rosen_is_ohos) { boundary_sanitize = true diff --git a/rosen/modules/render_service/core/drawable/rs_canvas_drawing_render_node_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_canvas_drawing_render_node_drawable.cpp index 5cc3cba57a..591d355ee7 100644 --- a/rosen/modules/render_service/core/drawable/rs_canvas_drawing_render_node_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_canvas_drawing_render_node_drawable.cpp @@ -250,11 +250,13 @@ void RSCanvasDrawingRenderNodeDrawable::ProcessCPURenderInBackgroundThread(std:: std::shared_ptr ctx, NodeId nodeId) { auto surface = surface_; - RSBackgroundThread::Instance().PostTask([this, cmds, surface, ctx, nodeId]() { - if (!cmds || cmds->IsEmpty() || !surface || !ctx) { + auto drawable = RSRenderNodeDrawableAdapter::GetDrawableById(nodeId); + RSBackgroundThread::Instance().PostTask([drawable, cmds, surface, ctx, nodeId]() { + if (!cmds || cmds->IsEmpty() || !surface || !ctx || !drawable) { return; } - if (surface != this->surface_) { + auto canvasDrawingDrawable = static_cast(drawable.get()); + if (surface != canvasDrawingDrawable->surface_) { return; } cmds->Playback(*surface->GetCanvas()); @@ -262,9 +264,9 @@ void RSCanvasDrawingRenderNodeDrawable::ProcessCPURenderInBackgroundThread(std:: if (image) { SKResourceManager::Instance().HoldResource(image); } - std::lock_guard lock(this->imageMutex_); - this->image_ = image; - auto task = [ctx, nodeId = renderNode_->GetId()] () { + std::lock_guard lock(canvasDrawingDrawable->imageMutex_); + canvasDrawingDrawable->image_ = image; + auto task = [ctx, nodeId] () { if (UNLIKELY(!ctx)) { return; } diff --git a/rosen/modules/render_service/core/drawable/rs_display_render_node_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_display_render_node_drawable.cpp index 80ec49308c..ea9fad5146 100644 --- a/rosen/modules/render_service/core/drawable/rs_display_render_node_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_display_render_node_drawable.cpp @@ -407,8 +407,12 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas) } if (uniParam->IsOpDropped() && CheckDisplayNodeSkip(displayNodeSp, params, processor)) { + RSMainThread::Instance()->SetFrameIsRender(false); + RSUniRenderThread::Instance().DvsyncRequestNextVsync(); return; } + RSMainThread::Instance()->SetFrameIsRender(true); + RSUniRenderThread::Instance().DvsyncRequestNextVsync(); // displayNodeSp to get rsSurface witch only used in renderThread auto renderFrame = RequestFrame(displayNodeSp, *params, processor); diff --git a/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp index b34d2c8dce..961fa4d412 100644 --- a/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp @@ -53,7 +53,7 @@ void RSRenderNodeShadowDrawable::Draw(Drawing::Canvas& canvas) return; } - SetSkipShadow(false); + SetSkip(SkipType::NONE); DrawRangeImpl(canvas, rect, 0, shadowIndex + 1); } diff --git a/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp index a45be47816..2b674798d2 100644 --- a/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp @@ -173,6 +173,7 @@ void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas) bool isSelfDrawingSurface = surfaceParams->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE; if (isSelfDrawingSurface && !surfaceParams->IsSpherizeValid()) { + SetSkip(surfaceParams->GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); rscanvas->Save(); } @@ -299,6 +300,7 @@ void RSSurfaceRenderNodeDrawable::CaptureSingleSurfaceNode(RSSurfaceRenderNode& auto nodeType = surfaceParams.GetSurfaceNodeType(); bool isSelfDrawingSurface = (nodeType == RSSurfaceNodeType::SELF_DRAWING_NODE); if (isSelfDrawingSurface && !surfaceParams.IsSpherizeValid()) { + SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); canvas.Save(); } @@ -389,6 +391,7 @@ void RSSurfaceRenderNodeDrawable::CaptureSurfaceInDisplay(RSSurfaceRenderNode& s auto nodeType = surfaceParams.GetSurfaceNodeType(); bool isSelfDrawingSurface = (nodeType == RSSurfaceNodeType::SELF_DRAWING_NODE); if (isSelfDrawingSurface) { + SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); canvas.Save(); } diff --git a/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp b/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp index c5fae96b46..d4e947f75f 100644 --- a/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp @@ -319,18 +319,10 @@ void RSMainThread::Init() } if (isUniRender_ && doDirectComposition_) { UpdateDisplayNodeScreenId(); - } - - if (!hasMark_) { - SetFrameIsRender(true); - } - hasMark_ = false; - // move rnv after mark rsnotrendering - if (needRequestNextVsyncAnimate_ || rsVSyncDistributor_->HasPendingUIRNV()) { - rsVSyncDistributor_->MarkRSAnimate(); - RequestNextVSync("animate", timestamp_); - } else { - rsVSyncDistributor_->UnmarkRSAnimate(); + if (!markRenderFlag_) { + SetFrameIsRender(true); + } + markRenderFlag_ = false; } InformHgmNodeInfo(); @@ -490,7 +482,9 @@ void RSMainThread::Init() RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate); RSMainThread::Instance()->SetIdleTimerExpiredFlag(idleTimerExpired); RS_TRACE_NAME_FMT("DVSyncIsOn: %d", this->rsVSyncDistributor_->IsDVsyncOn()); - if (!this->rsVSyncDistributor_->IsDVsyncOn()) { + if (forceUpdate) { + RSMainThread::Instance()->RequestNextVSync("ltpoForceUpdate"); + } else { RSMainThread::Instance()->RequestNextVSync(); } }); @@ -1453,6 +1447,14 @@ void RSMainThread::SetSurfaceCapProcFinished(bool flag) surfaceCapProcFinished_ = flag; } +bool RSMainThread::IsRequestedNextVSync() +{ + if (receiver_ != nullptr) { + return receiver_->IsRequestedNextVSync(); + } + return false; +} + void RSMainThread::ProcessHgmFrameRate(uint64_t timestamp) { RS_TRACE_FUNC(); @@ -1499,7 +1501,7 @@ bool RSMainThread::GetParallelCompositionEnabled() void RSMainThread::SetFrameIsRender(bool isRender) { - hasMark_ = true; + markRenderFlag_ = true; rsVSyncDistributor_->SetFrameIsRender(isRender); } @@ -1709,6 +1711,7 @@ void RSMainThread::Render() if (isUniRender_) { auto& hgmCore = OHOS::Rosen::HgmCore::Instance(); renderThreadParams_->SetTimestamp(hgmCore.GetCurrentTimestamp()); + renderThreadParams_->SetRequestNextVsyncFlag(needRequestNextVsyncAnimate_); renderThreadParams_->SetPendingScreenRefreshRate(hgmCore.GetPendingScreenRefreshRate()); renderThreadParams_->SetForceCommitLayer(isHardwareEnabledBufferUpdated_ || forceUpdateUniRenderFlag_); } diff --git a/rosen/modules/render_service/core/pipeline/rs_main_thread.h b/rosen/modules/render_service/core/pipeline/rs_main_thread.h index 182319b5dd..51d376a493 100644 --- a/rosen/modules/render_service/core/pipeline/rs_main_thread.h +++ b/rosen/modules/render_service/core/pipeline/rs_main_thread.h @@ -269,6 +269,15 @@ public: bool GetParallelCompositionEnabled(); std::shared_ptr GetFrameRateMgr() { return frameRateMgr_; }; void SetFrameIsRender(bool isRender); + bool GetMarkRenderFlag() const + { + return markRenderFlag_; + } + void ResetMarkRenderFlag() + { + markRenderFlag_ = false; + } + void PerfForBlurIfNeeded(); bool IsOnVsync() const @@ -296,6 +305,8 @@ public: skipJankAnimatorFrame_.store(skipJankAnimatorFrame); } + bool IsRequestedNextVSync(); + private: using TransactionDataIndexMap = std::unordered_map>>>; @@ -564,7 +575,7 @@ private: // for dvsync (animate requestNextVSync after mark rsnotrendering) bool needRequestNextVsyncAnimate_ = false; - bool hasMark_ = false; + bool markRenderFlag_ = false; bool forceUIFirstChanged_ = false; diff --git a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp index 20c0fd67ac..aaae7bae78 100644 --- a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp @@ -39,6 +39,7 @@ #include "pipeline/rs_task_dispatcher.h" #include "pipeline/rs_uni_render_judgement.h" #include "pipeline/rs_uni_ui_capture.h" +#include "pixel_map_from_surface.h" #include "platform/common/rs_log.h" #include "platform/common/rs_system_properties.h" #include "platform/ohos/rs_jank_stats.h" @@ -357,6 +358,22 @@ sptr RSRenderServiceConnection::CreateVSyncConnection(const st return conn; } +std::shared_ptr RSRenderServiceConnection::CreatePixelMapFromSurface(sptr surface, + const Rect &srcRect) +{ + OHOS::Media::Rect rect = { + .left = srcRect.x, + .top = srcRect.y, + .width = srcRect.w, + .height = srcRect.h, + }; + std::shared_ptr pixelmap = nullptr; + RSBackgroundThread::Instance().PostSyncTask([this, surface, rect, &pixelmap]() { + pixelmap = OHOS::Rosen::CreatePixelMapFromSurface(surface, rect); + }); + return pixelmap; +} + int32_t RSRenderServiceConnection::SetFocusAppInfo( int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId) { diff --git a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.h b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.h index 2fe3b10bc5..4f38b27755 100644 --- a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.h +++ b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.h @@ -81,6 +81,8 @@ private: uint64_t id, NodeId windowNodeId = 0) override; + std::shared_ptr CreatePixelMapFromSurface(sptr surface, const Rect &srcRect) override; + int32_t SetFocusAppInfo( int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId) override; @@ -297,7 +299,7 @@ private: std::unordered_set virtualScreenIds_; sptr screenChangeCallback_; sptr appVSyncDistributor_; - + #ifdef RS_PROFILER_ENABLED friend class RSProfiler; #endif diff --git a/rosen/modules/render_service/core/pipeline/rs_render_service_visitor.cpp b/rosen/modules/render_service/core/pipeline/rs_render_service_visitor.cpp index 426cc05ac0..b2a2364aec 100644 --- a/rosen/modules/render_service/core/pipeline/rs_render_service_visitor.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_render_service_visitor.cpp @@ -142,6 +142,7 @@ void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface if (node.SkipFrame(curScreenInfo.skipFrameInterval)) { RS_TRACE_NAME("SkipFrame, screenId:" + std::to_string(node.GetScreenId())); + screenManager->ForceRefreshOneFrameIfNoRNV(); return; } processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType()); diff --git a/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.cpp b/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.cpp index 0ce979e5a9..f5c208ad43 100644 --- a/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.cpp @@ -205,6 +205,12 @@ void RSUniRenderThread::Render() Drawing::Canvas canvas; rootNodeDrawable_->OnDraw(canvas); RSMainThread::Instance()->PerfForBlurIfNeeded(); + + if (RSMainThread::Instance()->GetMarkRenderFlag() == false) { + RSMainThread::Instance()->SetFrameIsRender(true); + DvsyncRequestNextVsync(); + } + RSMainThread::Instance()->ResetMarkRenderFlag(); } void RSUniRenderThread::ReleaseSelfDrawingNodeBuffer() @@ -459,6 +465,17 @@ void RSUniRenderThread::RenderServiceTreeDump(std::string& dumpString) const rootNodeDrawable_->DumpDrawableTree(0, dumpString); } +void RSUniRenderThread::DvsyncRequestNextVsync() +{ + if ((renderThreadParams_ && renderThreadParams_->GetRequestNextVsyncFlag()) || + RSMainThread::Instance()->rsVSyncDistributor_->HasPendingUIRNV()) { + RSMainThread::Instance()->rsVSyncDistributor_->MarkRSAnimate(); + RSMainThread::Instance()->RequestNextVSync("animate", renderThreadParams_->GetCurrentTimestamp()); + } else { + RSMainThread::Instance()->rsVSyncDistributor_->UnmarkRSAnimate(); + } +} + void RSUniRenderThread::UpdateDisplayNodeScreenId() { const std::shared_ptr rootNode = diff --git a/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.h b/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.h index d7e8648850..bac96209bd 100644 --- a/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.h +++ b/rosen/modules/render_service/core/pipeline/rs_uni_render_thread.h @@ -87,6 +87,8 @@ public: void ReleaseSurface(); void AddToReleaseQueue(std::shared_ptr&& surface); + void DvsyncRequestNextVsync(); + bool IsMainLooping() const { return mainLooping_.load(); diff --git a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp index 63a4d61147..c9483d4c0b 100644 --- a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp @@ -768,7 +768,7 @@ void RSUniRenderVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node) displayHasSecSurface_.emplace(currentVisitDisplay_, false); displayHasSkipSurface_.emplace(currentVisitDisplay_, false); hasCaptureWindow_.emplace(currentVisitDisplay_, false); - dirtySurfaceNodeMap_.clear(); + node.GetDirtySurfaceNodeMap().clear(); RS_TRACE_NAME("RSUniRender:PrepareDisplay " + std::to_string(currentVisitDisplay_)); curDisplayDirtyManager_ = node.GetDirtyManager(); @@ -1673,8 +1673,8 @@ void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNod if (node.IsHardwareForcedDisabled()) { return; } - bool bgTransport = - static_cast(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX; + bool bgTransport = !node.GetAncoForceDoDirect() && + (static_cast(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX); if (bgTransport) { RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%llu disabled by background color alpha < 1", node.GetName().c_str(), node.GetId()); @@ -1706,6 +1706,10 @@ void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector< return; } auto dst = hwcNode->GetDstRect(); + if (hwcNode->GetAncoForceDoDirect()) { + hwcRects.emplace_back(dst); + return; + } for (auto rect : hwcRects) { if (dst.Intersect(rect)) { RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%llu disabled by hwc node above", @@ -2606,7 +2610,7 @@ void RSUniRenderVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node) PrepareTypesOfSurfaceRenderNodeAfterUpdate(node); if (node.GetDstRectChanged() || (node.GetDirtyManager() && node.GetDirtyManager()->IsCurrentFrameDirty())) { - dirtySurfaceNodeMap_.emplace(nodeId, node.ReinterpretCastTo()); + curDisplayNode_->GetDirtySurfaceNodeMap().emplace(nodeId, node.ReinterpretCastTo()); } UpdateSurfaceRenderNodeScale(node); // Due to the alpha is updated in PrepareChildren, so PrepareChildren @@ -3434,6 +3438,11 @@ std::shared_ptr RSUniRenderVisitor::GetCacheImageFromMirrorNode( void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) { + curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo(); + if (!curDisplayNode_) { + ROSEN_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode, Current Display Node is nullptr."); + return; + } if (mirroredDisplays_.size() == 0) { node.SetCacheImgForCapture(nullptr); node.SetOffScreenCacheImgForCapture(nullptr); @@ -3451,6 +3460,7 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface if (node.SkipFrame(curScreenInfo.skipFrameInterval)) { RS_TRACE_NAME("SkipFrame, screenId:" + std::to_string(node.GetScreenId())); + screenManager->ForceRefreshOneFrameIfNoRNV(); return; } @@ -3596,6 +3606,8 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) RotateMirrorCanvasIfNeed(node, canvasRotation); PrepareOffscreenRender(*mirrorNode); canvas_->Save(); + Drawing::Region clipRegion; + clipRegion.Clone(clipRegion_); if (resetRotate_) { Drawing::Matrix invertMatrix; if (processor->GetScreenTransformMatrix().Invert(invertMatrix)) { @@ -3603,11 +3615,11 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) canvas_->ConcatMatrix(invertMatrix); // If both canvas and clipRegion have rotated, we need to reset the clipRegion Drawing::Path path; - if (clipRegion_.GetBoundaryPath(&path)) { + if (clipRegion.GetBoundaryPath(&path)) { path.Transform(invertMatrix); Drawing::Region clip; clip.SetRect(Drawing::RectI(0, 0, canvas_->GetWidth(), canvas_->GetHeight())); - clipRegion_.SetPath(path, clip); + clipRegion.SetPath(path, clip); } } } @@ -3619,7 +3631,7 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) canvas_->DetachBrush(); canvas_->Restore(); if (isOpDropped_ && !isDirtyRegionAlignedEnable_) { - ClipRegion(canvas_, clipRegion_); + ClipRegion(canvas_, clipRegion); } auto offScreenCacheImgForCapture = mirrorNode->GetOffScreenCacheImgForCapture(); if (offScreenCacheImgForCapture) { @@ -3696,7 +3708,7 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) curDisplayDirtyManager_->UpdateDirty(isDirtyRegionAlignedEnable_); UpdateHardwareNodeStatusBasedOnFilterRegion(node); } - if (isOpDropped_ && dirtySurfaceNodeMap_.empty() + if (isOpDropped_ && curDisplayNode_->GetDirtySurfaceNodeMap().empty() && !curDisplayDirtyManager_->IsCurrentFrameDirty()) { RS_LOGD("DisplayNode skip"); RS_TRACE_NAME("DisplayNode skip"); @@ -3848,7 +3860,7 @@ void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node) } } if (isOpDropped_ && !isDirtyRegionAlignedEnable_) { - clipRegion_ = region; + clipRegion_.Clone(region); ClipRegion(canvas_, region); if (!region.IsEmpty()) { canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT); @@ -4161,7 +4173,8 @@ void RSUniRenderVisitor::CalcDirtyDisplayRegion(std::shared_ptrGetDirtyManager(); if (isUIFirst_ && surfaceDirtyManager->IsCurrentFrameDirty()) { - dirtySurfaceNodeMap_.emplace(surfaceNode->GetId(), surfaceNode->ReinterpretCastTo()); + curDisplayNode_->GetDirtySurfaceNodeMap().emplace( + surfaceNode->GetId(), surfaceNode->ReinterpretCastTo()); } RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion(); if (surfaceNode->IsTransparent()) { @@ -4239,7 +4252,7 @@ void RSUniRenderVisitor::MergeDirtyRectIfNeed(std::shared_ptrIsLastFrameHardwareEnabled() || hwcNode->IsCurrentFrameBufferConsumed()) && appNode && appNode->GetDirtyManager()) { appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect()); - dirtySurfaceNodeMap_.emplace(appNode->GetId(), appNode); + curDisplayNode_->GetDirtySurfaceNodeMap().emplace(appNode->GetId(), appNode); } } @@ -4274,6 +4287,39 @@ RectI RSUniRenderVisitor::UpdateHardwareEnableList(std::vector& filterRec return filterDirty; } +void RSUniRenderVisitor::UpdateHardwareChildNodeStatus(std::shared_ptr& node, + std::vector& curHwcEnabledNodes) +{ + // remove invisible surface since occlusion + auto visibleRegion = node->GetVisibleRegion(); + for (auto subNode : node->GetChildHardwareEnabledNodes()) { + auto childNode = subNode.lock(); + if (!childNode) { + continue; + } + // recover disabled state before update + childNode->SetHardwareForcedDisabledStateByFilter(false); + if (!visibleRegion.IsIntersectWith(Occlusion::Rect(childNode->GetOldDirtyInSurface()))) { + continue; + } + bool isIntersected = false; + if (!isPhone_ || childNode->GetAncoForceDoDirect()) { + curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node)); + continue; + } + for (auto &hwcNode: curHwcEnabledNodes) { + if (childNode->GetDstRect().Intersect(hwcNode.first->GetDstRect())) { + childNode->SetHardwareForcedDisabledStateByFilter(true); + isIntersected = true; + break; + } + } + if (!isIntersected) { + curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node)); + } + } +} + void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr& node, std::vector& prevHwcEnabledNodes, std::shared_ptr& displayDirtyManager) @@ -4289,32 +4335,8 @@ void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptrGetChildrenNeedFilterRects(); // collect valid hwc surface which is not intersected with filterRects std::vector curHwcEnabledNodes; - // remove invisible surface since occlusion - auto visibleRegion = node->GetVisibleRegion(); - for (auto subNode : node->GetChildHardwareEnabledNodes()) { - auto childNode = subNode.lock(); - if (!childNode) { - continue; - } - // recover disabled state before update - childNode->SetHardwareForcedDisabledStateByFilter(false); - if (!visibleRegion.IsIntersectWith(Occlusion::Rect(childNode->GetOldDirtyInSurface()))) { - continue; - } - bool isIntersected = false; - if (isPhone_ && !childNode->GetAncoForceDoDirect()) { - for (auto &hwcNode: curHwcEnabledNodes) { - if (childNode->GetDstRect().Intersect(hwcNode.first->GetDstRect())) { - childNode->SetHardwareForcedDisabledStateByFilter(true); - isIntersected = true; - break; - } - } - } - if (!isPhone_ || !isIntersected) { - curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node)); - } - } + UpdateHardwareChildNodeStatus(node, curHwcEnabledNodes); + // Within App: disable hwc if intersect with filterRects dirtyManager->MergeDirtyRect(UpdateHardwareEnableList(filterRects, curHwcEnabledNodes)); // Among App: disable lower hwc layers if intersect with upper transparent appWindow @@ -5214,10 +5236,10 @@ void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node) bool backgroundTransparent = !node.GetAncoForceDoDirect() && (static_cast(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX); node.SetHardwareForcedDisabledState( - (node.IsHardwareForcedDisabledByFilter() || canvas_->GetAlpha() < 1.f || - backgroundTransparent || IsRosenWebHardwareDisabled(node, rotation) || + (node.IsHardwareForcedDisabledByFilter() || canvas_->GetAlpha() < 1.f || backgroundTransparent || + IsRosenWebHardwareDisabled(node, rotation) || RSUniRenderUtil::GetRotationDegreeFromMatrix(node.GetTotalMatrix()) % ROTATION_90 != 0 || - canvas_->GetBlendOffscreenLayerCnt() > 0) && + canvas_->HasOffscreenLayer()) && (!node.IsHardwareEnabledTopSurface() || node.HasSubNodeShouldPaint())); node.SetHardwareDisabledByCache(isUpdateCachedSurface_); node.ResetHardwareForcedDisabledBySrcRect(); diff --git a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.h b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.h index 8acba6d57e..f436d337e9 100644 --- a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.h +++ b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.h @@ -280,6 +280,9 @@ private: void UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode& displayNode); void UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr& node, std::vector>& prevHwcEnabledNodes); + void UpdateHardwareChildNodeStatus(std::shared_ptr& node, + std::vector& curHwcEnabledNodes); + void UpdateHardwareEnableList(std::vector& filterRects, std::vector>& validHwcNodes); // remove functions above when dirty region is enabled for foldable device diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp index e6951c9bf6..3113e126d3 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp +++ b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.cpp @@ -25,6 +25,7 @@ #include #include "param/sys_param.h" #include "common/rs_optional_trace.h" +#include "rs_trace.h" namespace OHOS { namespace Rosen { @@ -269,6 +270,18 @@ float RSScreenManager::GetScreenBrightnessNits(ScreenId id) } #endif +void RSScreenManager::ForceRefreshOneFrameIfNoRNV() +{ + auto mainThread = RSMainThread::Instance(); + if (mainThread != nullptr && !mainThread->IsRequestedNextVSync()) { + RS_TRACE_NAME("No RNV, ForceRefreshOneFrame"); + mainThread->PostTask([mainThread]() { + mainThread->SetDirtyFlag(); + }); + mainThread->ForceRefreshForUni(); + } +} + void RSScreenManager::OnHotPlug(std::shared_ptr &output, bool connected, void *data) { if (output == nullptr) { diff --git a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h index 1498e07db0..a7c278a98b 100644 --- a/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h +++ b/rosen/modules/render_service/core/screen_manager/rs_screen_manager.h @@ -186,6 +186,7 @@ public: #ifdef RS_SUBSCRIBE_SENSOR_ENABLE virtual void HandlePostureData(const SensorEvent * const event) = 0; #endif + virtual void ForceRefreshOneFrameIfNoRNV() = 0; }; sptr CreateOrGetScreenManager(); @@ -353,6 +354,7 @@ public: #ifdef RS_SUBSCRIBE_SENSOR_ENABLE void HandlePostureData(const SensorEvent * const event) override; #endif + void ForceRefreshOneFrameIfNoRNV() override; private: RSScreenManager(); diff --git a/rosen/modules/render_service/core/transaction/rs_render_service_connection_stub.cpp b/rosen/modules/render_service/core/transaction/rs_render_service_connection_stub.cpp index 8059aa37c8..e27b2af7ee 100644 --- a/rosen/modules/render_service/core/transaction/rs_render_service_connection_stub.cpp +++ b/rosen/modules/render_service/core/transaction/rs_render_service_connection_stub.cpp @@ -820,6 +820,46 @@ int RSRenderServiceConnectionStub::OnRemoteRequest( reply.WriteRemoteObject(conn->AsObject()); break; } + case static_cast(RSIRenderServiceConnectionInterfaceCode::CREATE_PIXEL_MAP_FROM_SURFACE): { + if (data.ReadInterfaceToken() != RSIRenderServiceConnection::GetDescriptor()) { + reply.WriteInt32(0); + ret = ERR_INVALID_STATE; + break; + } + auto remoteObject = data.ReadRemoteObject(); + if (remoteObject == nullptr) { + reply.WriteInt32(0); + ret = ERR_NULL_OBJECT; + break; + } + auto bufferProducer = iface_cast(remoteObject); + sptr surface = Surface::CreateSurfaceAsProducer(bufferProducer); + if (surface == nullptr) { + reply.WriteInt32(0); + ret = ERR_NULL_OBJECT; + break; + } + auto x = data.ReadInt32(); + auto y = data.ReadInt32(); + auto w = data.ReadInt32(); + auto h = data.ReadInt32(); + auto srcRect = Rect { + .x = x, + .y = y, + .w = w, + .h = h + }; + std::shared_ptr pixelMap = CreatePixelMapFromSurface(surface, srcRect); + if (pixelMap) { + reply.WriteBool(true); + if (!pixelMap->Marshalling(reply)) { + RS_LOGE("pixelMap Marshalling fail"); + } + } else { + reply.WriteBool(false); + } + break; + } case static_cast(RSIRenderServiceConnectionInterfaceCode::GET_SCREEN_HDR_CAPABILITY): { auto token = data.ReadInterfaceToken(); if (token != RSIRenderServiceConnection::GetDescriptor()) { diff --git a/rosen/modules/render_service_base/BUILD.gn b/rosen/modules/render_service_base/BUILD.gn index 18061e6270..4d734c3e84 100644 --- a/rosen/modules/render_service_base/BUILD.gn +++ b/rosen/modules/render_service_base/BUILD.gn @@ -80,6 +80,7 @@ ohos_source_set("render_service_base_src") { "src/animation/rs_animation_timing_protocol.cpp", "src/animation/rs_cubic_bezier_interpolator.cpp", "src/animation/rs_interpolator.cpp", + "src/animation/rs_particle_noise_field.cpp", "src/animation/rs_render_animation.cpp", "src/animation/rs_render_curve_animation.cpp", "src/animation/rs_render_interpolating_spring_animation.cpp", diff --git a/rosen/modules/render_service_base/include/animation/rs_particle_noise_field.h b/rosen/modules/render_service_base/include/animation/rs_particle_noise_field.h new file mode 100644 index 0000000000..1c7f23135f --- /dev/null +++ b/rosen/modules/render_service_base/include/animation/rs_particle_noise_field.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024-2024 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 ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H +#define ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H +#include +#include +#include + +#include "rs_render_particle.h" + +namespace OHOS { +namespace Rosen { +class RSB_EXPORT ParticleNoiseField { +public: + int fieldStrength_; + ShapeType fieldShape_; + Vector2f fieldSize_; + Vector2f fieldCenter_; + uint16_t fieldFeather_; + float noiseScale_; + float noiseFrequency_; + float noiseAmplitude_; + + explicit ParticleNoiseField(const int fieldStrength, const ShapeType& fieldShape, const Vector2f& fieldSize, + const Vector2f& fieldCenter, uint16_t fieldFeather, float noiseScale, float noiseFrequency, + float noiseAmplitude) + : fieldStrength_(fieldStrength), fieldShape_(fieldShape), fieldSize_(fieldSize), fieldCenter_(fieldCenter), + fieldFeather_(fieldFeather), noiseScale_(noiseScale), noiseFrequency_(noiseFrequency), + noiseAmplitude_(noiseAmplitude) + {} + ParticleNoiseField(const ParticleNoiseField& config) = default; + ParticleNoiseField& operator=(const ParticleNoiseField& config) = default; + ~ParticleNoiseField() = default; + + Vector2f ApplyField(const Vector2f& position); + Vector2f ApplyCurlNoise(const Vector2f& position); + + bool operator==(const ParticleNoiseField& rhs) const + { + bool equal = (this->fieldStrength_ == rhs.fieldStrength_) && (this->fieldShape_ == rhs.fieldShape_) && + (this->fieldSize_ == rhs.fieldSize_) && (this->fieldCenter_ == rhs.fieldCenter_) && + (this->fieldFeather_ == rhs.fieldFeather_) && (this->noiseScale_ == rhs.noiseScale_) && + (this->noiseFrequency_ == rhs.noiseFrequency_) && (this->noiseAmplitude_ == rhs.noiseAmplitude_); + return equal; + } + +private: + bool isPointInField( + const Vector2f& point, const ShapeType& fieldShape, const Vector2f& fieldCenter, float width, float height); + float calculateEllipseEdgeDistance(const Vector2f& direction); + float calculateDistanceToRectangleEdge( + const Vector2f& position, const Vector2f& direction, const Vector2f& center, const Vector2f& size); +}; + +class RSB_EXPORT PerlinNoise2D { +private: + std::vector p; // Permutation vector + float fade(float t); + float lerp(float t, float a, float b); + float grad(int hash, float x, float y); + float noiseScale_; + float noiseFrequency_; + float noiseAmplitude_; + +public: + PerlinNoise2D(float noiseScale, float noiseFrequency, float noiseAmplitude); + float noise(float x, float y); + Vector2f curl(float x, float y); +}; + +} // namespace Rosen +} // namespace OHOS + +#endif // ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H diff --git a/rosen/modules/render_service_base/include/animation/rs_render_particle.h b/rosen/modules/render_service_base/include/animation/rs_render_particle.h index ef0a795e6e..0636c30a56 100644 --- a/rosen/modules/render_service_base/include/animation/rs_render_particle.h +++ b/rosen/modules/render_service_base/include/animation/rs_render_particle.h @@ -31,14 +31,13 @@ namespace OHOS { namespace Rosen { -enum class ParticleUpdator: uint32_t { NONE = 0, RANDOM, CURVE }; +enum class ParticleUpdator : uint32_t { NONE = 0, RANDOM, CURVE }; -enum class ShapeType: uint32_t { RECT = 0, CIRCLE, ELLIPSE }; +enum class ShapeType : uint32_t { RECT = 0, CIRCLE, ELLIPSE }; -enum class ParticleType: uint32_t { - POINTS = 0, - IMAGES -}; +enum class ParticleType : uint32_t { POINTS = 0, IMAGES }; + +enum class DistributionType : uint32_t { UNIFORM = 0, GAUSSIAN }; template struct Range { @@ -172,6 +171,7 @@ public: class RSB_EXPORT RenderParticleColorParaType { public: Range colorVal_; + DistributionType distribution_; ParticleUpdator updator_; Range redRandom_; Range greenRandom_; @@ -179,14 +179,17 @@ public: Range alphaRandom_; std::vector>> valChangeOverLife_; - RenderParticleColorParaType(const Range& colorVal, const ParticleUpdator& updator, - const Range& redRandom, const Range& greenRandom, const Range& blueRandom, - const Range& alphaRandom, std::vector>> valChangeOverLife) - : colorVal_(colorVal), updator_(updator), redRandom_(redRandom), greenRandom_(greenRandom), - blueRandom_(blueRandom), alphaRandom_(alphaRandom), valChangeOverLife_(std::move(valChangeOverLife)) + RenderParticleColorParaType(const Range& colorVal, const DistributionType& distribution, + const ParticleUpdator& updator, const Range& redRandom, const Range& greenRandom, + const Range& blueRandom, const Range& alphaRandom, + std::vector>> valChangeOverLife) + : colorVal_(colorVal), distribution_(distribution), updator_(updator), redRandom_(redRandom), + greenRandom_(greenRandom), blueRandom_(blueRandom), alphaRandom_(alphaRandom), + valChangeOverLife_(std::move(valChangeOverLife)) {} RenderParticleColorParaType() - : colorVal_(), updator_(ParticleUpdator::NONE), redRandom_(), greenRandom_(), blueRandom_(), alphaRandom_() + : colorVal_(), distribution_(DistributionType::UNIFORM), updator_(ParticleUpdator::NONE), redRandom_(), + greenRandom_(), blueRandom_(), alphaRandom_() {} RenderParticleColorParaType(const RenderParticleColorParaType& color) = default; RenderParticleColorParaType& operator=(const RenderParticleColorParaType& color) = default; @@ -244,6 +247,7 @@ public: const Color& GetColorStartValue(); const Color& GetColorEndValue(); + const DistributionType& GetColorDistribution(); const ParticleUpdator& GetColorUpdator(); float GetRedRandomStart() const; float GetRedRandomEnd() const; @@ -354,23 +358,33 @@ public: bool IsAlive() const; void SetIsDead(); static float GetRandomValue(float min, float max); + void SetColor(); + int GenerateColorComponent(double mean, double stddev); Vector2f CalculateParticlePosition(const ShapeType& emitShape, const Vector2f& position, const Vector2f& emitSize); - Color Lerp(const Color& start, const Color& end, float t); std::shared_ptr particleParams_; bool operator==(const RSRenderParticle& rhs) { - return (position_ == rhs.position_) && (velocity_ == rhs.velocity_) && - (acceleration_ == rhs.acceleration_) && (scale_ == rhs.scale_) && (spin_ == rhs.spin_) && - (opacity_ == rhs.opacity_) && (color_ == rhs.color_) && (radius_ == rhs.radius_) && - (particleType_ == rhs.particleType_) && (activeTime_ == rhs.activeTime_) && + return (position_ == rhs.position_) && (velocity_ == rhs.velocity_) && (acceleration_ == rhs.acceleration_) && + (scale_ == rhs.scale_) && (spin_ == rhs.spin_) && (opacity_ == rhs.opacity_) && (color_ == rhs.color_) && + (radius_ == rhs.radius_) && (particleType_ == rhs.particleType_) && (activeTime_ == rhs.activeTime_) && (lifeTime_ == rhs.lifeTime_) && (imageSize_ == rhs.imageSize_); } + static Color Lerp(const Color& start, const Color& end, float t) + { + Color result; + result.SetRed(start.GetRed() + static_cast(std::round((end.GetRed() - start.GetRed()) * t))); + result.SetGreen(start.GetGreen() + static_cast(std::round((end.GetGreen() - start.GetGreen()) * t))); + result.SetBlue(start.GetBlue() + static_cast(std::round((end.GetBlue() - start.GetBlue()) * t))); + result.SetAlpha(start.GetAlpha() + static_cast(std::round((end.GetAlpha() - start.GetAlpha()) * t))); + return result; + } + private: - Vector2f position_ = {0.f, 0.f}; - Vector2f velocity_ = {0.f, 0.f}; - Vector2f acceleration_ = {0.f, 0.f}; + Vector2f position_ = { 0.f, 0.f }; + Vector2f velocity_ = { 0.f, 0.f }; + Vector2f acceleration_ = { 0.f, 0.f }; float scale_ = 1.f; float spin_ = 0.f; float opacity_ = 1.f; @@ -443,6 +457,7 @@ public: } friend class RSRenderParticleAnimation; + private: std::vector> renderParticleVector_; }; diff --git a/rosen/modules/render_service_base/include/animation/rs_render_particle_animation.h b/rosen/modules/render_service_base/include/animation/rs_render_particle_animation.h index 714db07dc9..324da0f366 100644 --- a/rosen/modules/render_service_base/include/animation/rs_render_particle_animation.h +++ b/rosen/modules/render_service_base/include/animation/rs_render_particle_animation.h @@ -18,6 +18,7 @@ #include +#include "rs_particle_noise_field.h" #include "rs_render_particle.h" #include "animation/rs_render_particle_system.h" @@ -45,6 +46,7 @@ public: } bool Animate(int64_t time) override; void UpdateEmitter(const std::shared_ptr& emitterUpdater); + void UpdateNoiseField(const std::shared_ptr& particleNoiseField); const std::shared_ptr& GetParticleSystem() { return particleSystem_; @@ -59,6 +61,7 @@ private: std::vector> particlesRenderParams_; std::shared_ptr particleSystem_; RSRenderParticleVector renderParticleVector_; + std::shared_ptr particleNoiseField_; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/include/animation/rs_render_particle_effector.h b/rosen/modules/render_service_base/include/animation/rs_render_particle_effector.h index 3a88c48fbc..5f45922865 100644 --- a/rosen/modules/render_service_base/include/animation/rs_render_particle_effector.h +++ b/rosen/modules/render_service_base/include/animation/rs_render_particle_effector.h @@ -17,6 +17,7 @@ #define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_RENDER_PARTICLE_EFFECTOR_H #include "rs_render_particle.h" +#include "rs_particle_noise_field.h" namespace OHOS { namespace Rosen { @@ -27,10 +28,10 @@ public: Vector4 CalculateColorInt(const std::shared_ptr& particle, Vector4 colorInt, Vector4 colorF, Vector4 colorSpeed, float deltaTime); - float UpdateCurveValue( + void UpdateCurveValue(float& value, const std::vector>>& valChangeOverLife, int64_t activeTime); - Color UpdateColorCurveValue( + void UpdateColorCurveValue(Color& color, const std::vector>>& valChangeOverLife, int64_t activeTime); void UpdateColor(const std::shared_ptr& particle, float deltaTime); @@ -45,11 +46,13 @@ public: void UpdateAccelerationValue(const std::shared_ptr& particle, float deltaTime); - void UpdatePosition(const std::shared_ptr& particle, float deltaTime); + void UpdatePosition(const std::shared_ptr& particle, + const std::shared_ptr& particleNoiseField, float deltaTime); void UpdateActiveTime(const std::shared_ptr& particle, int64_t deltaTime); - void Update(const std::shared_ptr& particle, int64_t deltaTime); + void Update(const std::shared_ptr& particle, + const std::shared_ptr& particleNoiseField, int64_t deltaTime); }; } // namespace Rosen diff --git a/rosen/modules/render_service_base/include/animation/rs_render_particle_system.h b/rosen/modules/render_service_base/include/animation/rs_render_particle_system.h index 195fc6a14e..6c9f5d7bff 100644 --- a/rosen/modules/render_service_base/include/animation/rs_render_particle_system.h +++ b/rosen/modules/render_service_base/include/animation/rs_render_particle_system.h @@ -32,6 +32,7 @@ public: bool IsFinish(const std::vector>& activeParticles); void UpdateEmitter( const uint32_t& emitterIndex, const Vector2f& position, const Vector2f& emitSize, const int& emitRate); + void UpdateNoiseField(const std::shared_ptr& particleNoiseField); const std::vector>& GetParticleEmitter() { return emitters_; @@ -40,6 +41,7 @@ public: private: std::vector> particlesRenderParams_ = {}; std::vector> emitters_ = {}; + std::shared_ptr particleNoiseField_; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/include/command/rs_node_command.h b/rosen/modules/render_service_base/include/command/rs_node_command.h index 57240828ed..11ce3960ac 100644 --- a/rosen/modules/render_service_base/include/command/rs_node_command.h +++ b/rosen/modules/render_service_base/include/command/rs_node_command.h @@ -43,6 +43,7 @@ enum RSNodeCommandType : uint16_t { UPDATE_MODIFIER_GRADIENT_BLUR_PTR, UPDATE_MODIFIER_MOTION_BLUR_PTR, UPDATE_MODIFIER_EMITTER_UPDATER_PTR, + UPDATE_MODIFIER_NOISE_FIELD_PTR, UPDATE_MODIFIER_SHADER_PTR, UPDATE_MODIFIER_VECTOR2F, UPDATE_MODIFIER_VECTOR4_BORDER_STYLE, @@ -183,6 +184,10 @@ ADD_COMMAND(RSUpdatePropertyEmitterUpdater, ARG(RS_NODE, UPDATE_MODIFIER_EMITTER_UPDATER_PTR, RSNodeCommandHelper::UpdateModifier>, NodeId, std::shared_ptr, PropertyId, PropertyUpdateType)) +ADD_COMMAND(RSUpdatePropertyParticleNoiseField, + ARG(RS_NODE, UPDATE_MODIFIER_NOISE_FIELD_PTR, + RSNodeCommandHelper::UpdateModifier>, + NodeId, std::shared_ptr, PropertyId, PropertyUpdateType)) ADD_COMMAND(RSUpdatePropertyShader, ARG(RS_NODE, UPDATE_MODIFIER_SHADER_PTR, RSNodeCommandHelper::UpdateModifier>, NodeId, std::shared_ptr, PropertyId, PropertyUpdateType)) diff --git a/rosen/modules/render_service_base/include/common/rs_background_thread.h b/rosen/modules/render_service_base/include/common/rs_background_thread.h index e9f2a9cbe7..763871fbee 100644 --- a/rosen/modules/render_service_base/include/common/rs_background_thread.h +++ b/rosen/modules/render_service_base/include/common/rs_background_thread.h @@ -29,10 +29,11 @@ class RSB_EXPORT RSBackgroundThread final { public: static RSBackgroundThread& Instance(); void PostTask(const std::function& task); + void PostSyncTask(const std::function& task); #if defined(RS_ENABLE_UNI_RENDER) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)) void InitRenderContext(RenderContext* context); void CleanGrResource(); - void SetGrResourceFinishFlag(bool resourceFinish); + void SetGrResourceFinishFlag(const bool& resourceFinish); bool GetGrResourceFinishFlag(); std::shared_ptr GetShareGPUContext() const; #endif diff --git a/rosen/modules/render_service_base/include/drawable/rs_drawable.h b/rosen/modules/render_service_base/include/drawable/rs_drawable.h index a099555250..d88f11c1d1 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_drawable.h +++ b/rosen/modules/render_service_base/include/drawable/rs_drawable.h @@ -40,6 +40,7 @@ enum class RSDrawableSlot : int8_t { TRANSITION, ENV_FOREGROUND_COLOR, SHADOW, + FOREGROUND_FILTER, OUTLINE, // BG properties in Bounds Clip @@ -72,7 +73,7 @@ enum class RSDrawableSlot : int8_t { COLOR_FILTER, LIGHT_UP_EFFECT, DYNAMIC_DIM, - FOREGROUND_FILTER, + COMPOSITING_FILTER, FOREGROUND_COLOR, FG_RESTORE_BOUNDS, @@ -85,6 +86,7 @@ enum class RSDrawableSlot : int8_t { // Restore state RESTORE_BLEND_MODE, + RESTORE_FOREGROUND_FILTER, RESTORE_ALL, // Annotations: Please remember to update this when new slots are added. diff --git a/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h b/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h index 8f8fb1bfbd..2d54532c86 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h +++ b/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h @@ -204,13 +204,18 @@ private: class RSEndBlendModeDrawable : public RSDrawable { public: - RSEndBlendModeDrawable() = default; + RSEndBlendModeDrawable(int blendApplyType) : blendApplyType_(blendApplyType) {} ~RSEndBlendModeDrawable() override = default; static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); bool OnUpdate(const RSRenderNode& node) override; - void OnSync() override {}; + void OnSync() override; Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + bool needSync_ = false; + int blendApplyType_; + int stagingBlendApplyType_; }; } // namespace DrawableV2 } // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_foreground.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_foreground.h index e48291ab87..9987c17fbd 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_foreground.h +++ b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_foreground.h @@ -96,10 +96,10 @@ private: float stagingDynamicDimDegree_ = 1.0f; }; -class RSForegroundFilterDrawable : public RSFilterDrawable { +class RSCompositingFilterDrawable : public RSFilterDrawable { public: - RSForegroundFilterDrawable() = default; - ~RSForegroundFilterDrawable() override = default; + RSCompositingFilterDrawable() = default; + ~RSCompositingFilterDrawable() override = default; static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); bool OnUpdate(const RSRenderNode& node) override; @@ -109,6 +109,39 @@ public: } }; +// foregroundFilter +class RSForegroundFilterDrawable : public RSDrawable { +public: + RSForegroundFilterDrawable() = default; + ~RSForegroundFilterDrawable() override = default; + + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + void OnSync() override; + Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + bool needSync_ = false; + RectF boundsRect_; + RectF stagingBoundsRect_; +}; + +class RSForegroundFilterRestoreDrawable : public RSDrawable { +public: + RSForegroundFilterRestoreDrawable() = default; + ~RSForegroundFilterRestoreDrawable() override = default; + + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + void OnSync() override; + Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + bool needSync_ = false; + std::shared_ptr foregroundFilter_; + std::shared_ptr stagingForegroundFilter_; +}; + class RSForegroundColorDrawable : public RSPropertyDrawable { public: RSForegroundColorDrawable(std::shared_ptr&& drawCmdList) diff --git a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h index 7e151a0ec5..f0dfa1e320 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h +++ b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h @@ -32,6 +32,8 @@ public: Drawing::Path& drPath, Drawing::Matrix& matrix, RSColor& colorPicked); static void GetDarkColor(RSColor& color); static void CeilMatrixTrans(Drawing::Canvas* canvas); + static void BeginForegroundFilter(RSPaintFilterCanvas& canvas, const RectF& bounds); + static void DrawForegroundFilter(RSPaintFilterCanvas& canvas, const std::shared_ptr& rsFilter); static void DrawFilter(Drawing::Canvas* canvas, const std::shared_ptr& rsFilter, const std::unique_ptr& cacheManager, const bool isForegroundFilter, bool shouldClearFilteredCache); @@ -54,7 +56,7 @@ public: static void DrawUseEffect(RSPaintFilterCanvas* canvas); static void BeginBlendMode(RSPaintFilterCanvas& canvas, int blendMode, int blendModeApplyType); - static void EndBlendMode(RSPaintFilterCanvas& canvas); + static void EndBlendMode(RSPaintFilterCanvas& canvas, int blendModeApplyType); static Color CalculateInvertColor(const Color& backgroundColor); static Color GetInvertBackgroundColor(RSPaintFilterCanvas& canvas, bool needClipToBounds, diff --git a/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h b/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h index 4970b6849a..7949f4d3b1 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h +++ b/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h @@ -33,6 +33,12 @@ class Canvas; } namespace DrawableV2 { +enum class SkipType : uint8_t { + NONE = 0, + SKIP_SHADOW = 1, + SKIP_BACKGROUND_COLOR = 2 +}; + class RSB_EXPORT RSRenderNodeDrawableAdapter { public: explicit RSRenderNodeDrawableAdapter(std::shared_ptr&& node); @@ -55,10 +61,7 @@ public: static SharedPtr GetDrawableById(NodeId id); static SharedPtr OnGenerateShadowDrawable(const std::shared_ptr& node); - void SetSkipShadow(bool skip) - { - skipShadow_ = skip; - } + void SetSkip(SkipType type); protected: // Util functions @@ -109,7 +112,7 @@ private: static Generator shadowGenerator_; static std::map RenderNodeDrawableCache; static inline std::mutex cacheMapMutex_; - bool skipShadow_ = false; + int8_t skipIndex_ = -1; }; } // namespace DrawableV2 diff --git a/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h b/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h index fdc190db08..4bf636b58c 100644 --- a/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h +++ b/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h @@ -27,122 +27,123 @@ namespace Rosen { // b. g_propertyToDrawableLut in rs_drawable_content.cpp // 2. Property modifier(i.e. to be applied to RSProperties) MUST be added before CUSTOM enum, else wise it will not work enum class RSModifierType : int16_t { - INVALID = 0, // 0 - BOUNDS, // 1 - FRAME, // 2 - POSITION_Z, // 3 - PIVOT, // 4 - PIVOT_Z, // 5 - QUATERNION, // 6 - ROTATION, // 7 - ROTATION_X, // 8 - ROTATION_Y, // 9 - CAMERA_DISTANCE, // 10 - SCALE, // 11 - SKEW, // 12 - PERSP, // 13 - TRANSLATE, // 14 - TRANSLATE_Z, // 15 - SUBLAYER_TRANSFORM, // 16 - CORNER_RADIUS, // 17 - ALPHA, // 18 - ALPHA_OFFSCREEN, // 19 - FOREGROUND_COLOR, // 20 - BACKGROUND_COLOR, // 21 - BACKGROUND_SHADER, // 22 - BG_IMAGE, // 23 - BG_IMAGE_INNER_RECT, // 24 - BG_IMAGE_WIDTH, // 25 - BG_IMAGE_HEIGHT, // 26 - BG_IMAGE_POSITION_X, // 27 - BG_IMAGE_POSITION_Y, // 28 - SURFACE_BG_COLOR, // 29 - BORDER_COLOR, // 30 - BORDER_WIDTH, // 31 - BORDER_STYLE, // 32 - FILTER, // 33 - BACKGROUND_FILTER, // 34 - LINEAR_GRADIENT_BLUR_PARA, // 35 - DYNAMIC_LIGHT_UP_RATE, // 36 - DYNAMIC_LIGHT_UP_DEGREE, // 37 - FRAME_GRAVITY, // 38 - CLIP_RRECT, // 39 - CLIP_BOUNDS, // 40 - CLIP_TO_BOUNDS, // 41 - CLIP_TO_FRAME, // 42 - VISIBLE, // 43 - SHADOW_COLOR, // 44 - SHADOW_OFFSET_X, // 45 - SHADOW_OFFSET_Y, // 46 - SHADOW_ALPHA, // 47 - SHADOW_ELEVATION, // 48 - SHADOW_RADIUS, // 49 - SHADOW_PATH, // 50 - SHADOW_MASK, // 51 - SHADOW_COLOR_STRATEGY, // 52 - MASK, // 53 - SPHERIZE, // 54 - LIGHT_UP_EFFECT, // 55 - PIXEL_STRETCH, // 56 - PIXEL_STRETCH_PERCENT, // 57 - USE_EFFECT, // 58 - COLOR_BLEND_MODE, // 59 - COLOR_BLEND_APPLY_TYPE, // 60 - SANDBOX, // 61 - GRAY_SCALE, // 62 - BRIGHTNESS, // 63 - CONTRAST, // 64 - SATURATE, // 65 - SEPIA, // 66 - INVERT, // 67 - AIINVERT, // 68 - SYSTEMBAREFFECT, // 69 - HUE_ROTATE, // 70 - COLOR_BLEND, // 71 - PARTICLE, // 72 - SHADOW_IS_FILLED, // 73 - OUTLINE_COLOR, // 74 - OUTLINE_WIDTH, // 75 - OUTLINE_STYLE, // 76 - OUTLINE_RADIUS, // 77 - USE_SHADOW_BATCHING, // 78 - GREY_COEF, // 79 - LIGHT_INTENSITY, // 80 - LIGHT_COLOR, // 81 - LIGHT_POSITION, // 82 - ILLUMINATED_BORDER_WIDTH, // 83 - ILLUMINATED_TYPE, // 84 - BLOOM, // 85 - PARTICLE_EMITTER_UPDATER, // 86 - FOREGROUND_EFFECT_RADIUS, // 87 - MOTION_BLUR_PARA, // 88 - DYNAMIC_DIM_DEGREE, // 89 - BACKGROUND_BLUR_RADIUS, // 90 - BACKGROUND_BLUR_SATURATION, // 91 - BACKGROUND_BLUR_BRIGHTNESS, // 92 - BACKGROUND_BLUR_MASK_COLOR, // 93 - BACKGROUND_BLUR_COLOR_MODE, // 94 - BACKGROUND_BLUR_RADIUS_X, // 95 - BACKGROUND_BLUR_RADIUS_Y, // 96 - FOREGROUND_BLUR_RADIUS, // 97 - FOREGROUND_BLUR_SATURATION, // 98 - FOREGROUND_BLUR_BRIGHTNESS, // 99 - FOREGROUND_BLUR_MASK_COLOR, // 100 - FOREGROUND_BLUR_COLOR_MODE, // 101 - FOREGROUND_BLUR_RADIUS_X, // 102 - FOREGROUND_BLUR_RADIUS_Y, // 103 - CUSTOM, // 104 - EXTENDED, // 105 - TRANSITION, // 106 - BACKGROUND_STYLE, // 107 - CONTENT_STYLE, // 108 - FOREGROUND_STYLE, // 109 - OVERLAY_STYLE, // 110 - NODE_MODIFIER, // 111 - ENV_FOREGROUND_COLOR, // 112 - ENV_FOREGROUND_COLOR_STRATEGY, // 113 - GEOMETRYTRANS, // 114 - CHILDREN, // 115, PLACEHOLDER, no such modifier, but we need a dirty flag + INVALID = 0, + BOUNDS, + FRAME, + POSITION_Z, + PIVOT, + PIVOT_Z, + QUATERNION, + ROTATION, + ROTATION_X, + ROTATION_Y, + CAMERA_DISTANCE, + SCALE, + SKEW, + PERSP, + TRANSLATE, + TRANSLATE_Z, + SUBLAYER_TRANSFORM, + CORNER_RADIUS, + ALPHA, + ALPHA_OFFSCREEN, + FOREGROUND_COLOR, + BACKGROUND_COLOR, + BACKGROUND_SHADER, + BG_IMAGE, + BG_IMAGE_INNER_RECT, + BG_IMAGE_WIDTH, + BG_IMAGE_HEIGHT, + BG_IMAGE_POSITION_X, + BG_IMAGE_POSITION_Y, + SURFACE_BG_COLOR, + BORDER_COLOR, + BORDER_WIDTH, + BORDER_STYLE, + FILTER, + BACKGROUND_FILTER, + LINEAR_GRADIENT_BLUR_PARA, + DYNAMIC_LIGHT_UP_RATE, + DYNAMIC_LIGHT_UP_DEGREE, + FRAME_GRAVITY, + CLIP_RRECT, + CLIP_BOUNDS, + CLIP_TO_BOUNDS, + CLIP_TO_FRAME, + VISIBLE, + SHADOW_COLOR, + SHADOW_OFFSET_X, + SHADOW_OFFSET_Y, + SHADOW_ALPHA, + SHADOW_ELEVATION, + SHADOW_RADIUS, + SHADOW_PATH, + SHADOW_MASK, + SHADOW_COLOR_STRATEGY, + MASK, + SPHERIZE, + LIGHT_UP_EFFECT, + PIXEL_STRETCH, + PIXEL_STRETCH_PERCENT, + USE_EFFECT, + COLOR_BLEND_MODE, + COLOR_BLEND_APPLY_TYPE, + SANDBOX, + GRAY_SCALE, + BRIGHTNESS, + CONTRAST, + SATURATE, + SEPIA, + INVERT, + AIINVERT, + SYSTEMBAREFFECT, + HUE_ROTATE, + COLOR_BLEND, + PARTICLE, + SHADOW_IS_FILLED, + OUTLINE_COLOR, + OUTLINE_WIDTH, + OUTLINE_STYLE, + OUTLINE_RADIUS, + USE_SHADOW_BATCHING, + GREY_COEF, + LIGHT_INTENSITY, + LIGHT_COLOR, + LIGHT_POSITION, + ILLUMINATED_BORDER_WIDTH, + ILLUMINATED_TYPE, + BLOOM, + PARTICLE_EMITTER_UPDATER, + PARTICLE_NOISE_FIELD, + FOREGROUND_EFFECT_RADIUS, + MOTION_BLUR_PARA, + DYNAMIC_DIM_DEGREE, + BACKGROUND_BLUR_RADIUS, + BACKGROUND_BLUR_SATURATION, + BACKGROUND_BLUR_BRIGHTNESS, + BACKGROUND_BLUR_MASK_COLOR, + BACKGROUND_BLUR_COLOR_MODE, + BACKGROUND_BLUR_RADIUS_X, + BACKGROUND_BLUR_RADIUS_Y, + FOREGROUND_BLUR_RADIUS, + FOREGROUND_BLUR_SATURATION, + FOREGROUND_BLUR_BRIGHTNESS, + FOREGROUND_BLUR_MASK_COLOR, + FOREGROUND_BLUR_COLOR_MODE, + FOREGROUND_BLUR_RADIUS_X, + FOREGROUND_BLUR_RADIUS_Y, + CUSTOM, + EXTENDED, + TRANSITION, + BACKGROUND_STYLE, + CONTENT_STYLE, + FOREGROUND_STYLE, + OVERLAY_STYLE, + NODE_MODIFIER, + ENV_FOREGROUND_COLOR, + ENV_FOREGROUND_COLOR_STRATEGY, + GEOMETRYTRANS, + CHILDREN, // PLACEHOLDER, no such modifier, but we need a dirty flag MAX_RS_MODIFIER_TYPE, }; using ModifierDirtyTypes = std::bitset(RSModifierType::MAX_RS_MODIFIER_TYPE)>; diff --git a/rosen/modules/render_service_base/include/modifier/rs_modifiers_def.in b/rosen/modules/render_service_base/include/modifier/rs_modifiers_def.in index 82f0f8db20..4aa0fbca37 100644 --- a/rosen/modules/render_service_base/include/modifier/rs_modifiers_def.in +++ b/rosen/modules/render_service_base/include/modifier/rs_modifiers_def.in @@ -100,6 +100,8 @@ DECLARE_NOANIMATABLE_MODIFIER(MotionBlurPara, std::shared_ptr, DECLARE_NOANIMATABLE_MODIFIER(EmitterUpdater, std::shared_ptr, PARTICLE_EMITTER_UPDATER, Foreground) +DECLARE_NOANIMATABLE_MODIFIER(ParticleNoiseField, std::shared_ptr, PARTICLE_NOISE_FIELD, Foreground) + DECLARE_NOANIMATABLE_MODIFIER(FrameGravity, Gravity, FRAME_GRAVITY, Appearance) DECLARE_ANIMATABLE_MODIFIER(ClipRRect, RRect, CLIP_RRECT, Replace, Appearance, MEDIUM) diff --git a/rosen/modules/render_service_base/include/params/rs_render_thread_params.h b/rosen/modules/render_service_base/include/params/rs_render_thread_params.h index 180dacd5c6..b5c1f738ea 100644 --- a/rosen/modules/render_service_base/include/params/rs_render_thread_params.h +++ b/rosen/modules/render_service_base/include/params/rs_render_thread_params.h @@ -138,6 +138,16 @@ public: return isForceCommitLayer_; } + void SetRequestNextVsyncFlag(bool flag) + { + needRequestNextVsyncAnimate_ = flag; + } + + bool GetRequestNextVsyncFlag() const + { + return needRequestNextVsyncAnimate_; + } + void SetOnVsyncStartTime(int64_t time) { onVsyncStartTime_ = time; @@ -191,6 +201,9 @@ private: Occlusion::Region accumulatedDirtyRegion_; bool watermarkFlag_ = false; std::shared_ptr watermarkImg_ = nullptr; + + bool needRequestNextVsyncAnimate_ = false; + int64_t onVsyncStartTime_ = TIMESTAMP_INITIAL; int64_t onVsyncStartTimeSteady_ = TIMESTAMP_INITIAL; bool isUniRenderAndOnVsync_ = false; diff --git a/rosen/modules/render_service_base/include/pipeline/rs_display_render_node.h b/rosen/modules/render_service_base/include/pipeline/rs_display_render_node.h index ef6d0906dd..ce21b74fd2 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_display_render_node.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_display_render_node.h @@ -29,6 +29,7 @@ #include "memory/rs_memory_track.h" #include "pipeline/rs_render_node.h" #include "pipeline/rs_surface_handler.h" +#include "rs_surface_render_node.h" #include #include "screen_manager/rs_screen_info.h" #ifdef NEW_RENDER_CONTEXT @@ -308,6 +309,11 @@ public: void SetMainAndLeashSurfaceDirty(bool isDirty); + std::map>& GetDirtySurfaceNodeMap() + { + return dirtySurfaceNodeMap_; + } + protected: void OnSync() override; private: @@ -357,6 +363,8 @@ private: // Use in vulkan parallel rendering bool isParallelDisplayNode_ = false; + + std::map> dirtySurfaceNodeMap_; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h b/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h index 1358ad4368..d031949e69 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_draw_cmd.h @@ -33,7 +33,7 @@ #include "external_window.h" #endif #ifdef RS_ENABLE_VK -#include "../../src/platform/ohos/backend/native_buffer_utils.h" +#include "backend/native_buffer_utils.h" #endif namespace OHOS { diff --git a/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h b/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h index b79ca0f6de..f4acd21cd0 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h @@ -137,7 +137,7 @@ class RSB_EXPORT RSPaintFilterCanvas : public RSPaintFilterCanvasBase { public: RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha = 1.0f); RSPaintFilterCanvas(Drawing::Surface* surface, float alpha = 1.0f); - ~RSPaintFilterCanvas() override {}; + ~RSPaintFilterCanvas() override = default;; void CopyConfiguration(const RSPaintFilterCanvas& other); void PushDirtyRegion(Drawing::Region& resultRegion); @@ -162,11 +162,10 @@ public: int GetEnvSaveCount() const; void RestoreEnvToCount(int count); + // blendmode related + void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override; void SetBlendMode(std::optional blendMode); - int GetBlendOffscreenLayerCnt() const - { - return 0; - }; + bool HasOffscreenLayer() const; // save/restore utils struct SaveStatus { @@ -271,9 +270,8 @@ protected: Color envForegroundColor_; std::shared_ptr effectData_; std::optional blendMode_; + bool hasOffscreenLayer_; }; - const std::stack& GetAlphaStack(); - const std::stack& GetEnvStack(); bool OnFilter() const override; inline bool OnFilterWithBrush(Drawing::Brush& brush) const override diff --git a/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h b/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h index 4157044547..7353622ae8 100644 --- a/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h +++ b/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h @@ -24,8 +24,8 @@ class RSCanvasListener; class RSB_EXPORT RSListenedCanvas : public RSPaintFilterCanvas { public: - RSListenedCanvas(Drawing::Canvas& canvas, float alpha = 1.0f); - RSListenedCanvas(Drawing::Surface& surface, float alpha = 1.0f); + RSListenedCanvas(Drawing::Canvas& canvas); + RSListenedCanvas(Drawing::Surface& surface); void SetListener(const std::shared_ptr& listener); // shapes diff --git a/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection.h b/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection.h index 8f50942621..bfc62d3b72 100644 --- a/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection.h +++ b/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection.h @@ -65,6 +65,9 @@ public: uint64_t id = 0, NodeId windowNodeId = 0) = 0; + virtual std::shared_ptr CreatePixelMapFromSurface(sptr surface, + const Rect &srcRect) = 0; + virtual int32_t SetFocusAppInfo( int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId) = 0; diff --git a/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection_ipc_interface_code.h b/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection_ipc_interface_code.h index 5803f6224f..5de6ea0a79 100644 --- a/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection_ipc_interface_code.h +++ b/rosen/modules/render_service_base/include/platform/ohos/rs_irender_service_connection_ipc_interface_code.h @@ -66,6 +66,7 @@ enum class RSIRenderServiceConnectionInterfaceCode : CodeUnderlyingType { SET_VIRTUAL_MIRROR_SCREEN_SCALE_MODE, GET_SCREEN_GAMUT_MAP, CREATE_VSYNC_CONNECTION, + CREATE_PIXEL_MAP_FROM_SURFACE, GET_SCREEN_HDR_CAPABILITY, SET_PIXEL_FORMAT, GET_PIXEL_FORMAT, diff --git a/rosen/modules/render_service_base/include/property/rs_properties.h b/rosen/modules/render_service_base/include/property/rs_properties.h index e362f5357b..cd0be708b8 100644 --- a/rosen/modules/render_service_base/include/property/rs_properties.h +++ b/rosen/modules/render_service_base/include/property/rs_properties.h @@ -22,6 +22,7 @@ #include #include "animation/rs_render_particle.h" +#include "animation/rs_particle_noise_field.h" #include "common/rs_macros.h" #include "common/rs_matrix3.h" #include "common/rs_vector4.h" @@ -231,6 +232,7 @@ public: void SetBackgroundFilter(const std::shared_ptr& backgroundFilter); void SetLinearGradientBlurPara(const std::shared_ptr& para); void SetEmitterUpdater(const std::shared_ptr& para); + void SetParticleNoiseField(const std::shared_ptr& para); void SetDynamicLightUpRate(const std::optional& rate); void SetDynamicLightUpDegree(const std::optional& lightUpDegree); void SetDynamicDimDegree(const std::optional& DimDegree); @@ -239,6 +241,7 @@ public: const std::shared_ptr& GetBackgroundFilter() const; const std::shared_ptr& GetLinearGradientBlurPara() const; const std::shared_ptr& GetEmitterUpdater() const; + const std::shared_ptr& GetParticleNoiseField() const; void IfLinearGradientBlurInvalid(); const std::shared_ptr& GetFilter() const; const std::shared_ptr& GetMotionBlurPara() const; @@ -522,6 +525,7 @@ private: std::shared_ptr linearGradientBlurPara_ = nullptr; std::shared_ptr motionBlurPara_ = nullptr; std::shared_ptr emitterUpdater_ = nullptr; + std::shared_ptr particleNoiseField_ = nullptr; std::shared_ptr border_ = nullptr; std::shared_ptr outline_ = nullptr; std::shared_ptr clipPath_ = nullptr; diff --git a/rosen/modules/render_service_base/include/render/rs_border.h b/rosen/modules/render_service_base/include/render/rs_border.h index a3ba4c24af..94ff1f6110 100644 --- a/rosen/modules/render_service_base/include/render/rs_border.h +++ b/rosen/modules/render_service_base/include/render/rs_border.h @@ -90,6 +90,10 @@ public: const Drawing::Point& innerRectCenter) const; private: + Drawing::Point GetTLIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const; + Drawing::Point GetTRIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const; + Drawing::Point GetBLIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const; + Drawing::Point GetBRIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const; // Vectors containing uniform or four-sided border attributes. // If four-sided, the order of contents is left, top, right, bottom. std::vector colors_; diff --git a/rosen/modules/render_service_base/include/render/rs_kawase_blur.h b/rosen/modules/render_service_base/include/render/rs_kawase_blur.h index fe7127f227..e291d3813c 100644 --- a/rosen/modules/render_service_base/include/render/rs_kawase_blur.h +++ b/rosen/modules/render_service_base/include/render/rs_kawase_blur.h @@ -27,7 +27,7 @@ namespace Rosen { struct KawaseParameter { Drawing::Rect src; Drawing::Rect dst; - int radius; + int radius = 0; std::shared_ptr colorFilter; float alpha = 0.f; @@ -49,6 +49,13 @@ public: } private: + struct BlurParams { + int numberOfPasses = 1; + int width = 0; + int height = 0; + float radiusByPass = 0.f; + }; + KawaseBlurFilter(); ~KawaseBlurFilter(); KawaseBlurFilter(const KawaseBlurFilter& filter); @@ -59,6 +66,8 @@ private: const KawaseParameter& param, std::shared_ptr& checkedImage); void OutputOriginalImage(Drawing::Canvas& canvas, const std::shared_ptr& image, const KawaseParameter& param); + std::shared_ptr ExecutePingPongBlur(Drawing::Canvas& canvas, + const std::shared_ptr& input, const KawaseParameter& kParam, const BlurParams& bParam) const; bool ApplyBlur(Drawing::Canvas& canvas, const std::shared_ptr& image, const std::shared_ptr& blurImage, const KawaseParameter& param) const; void ComputeRadiusAndScale(int radius); diff --git a/rosen/modules/render_service_base/include/transaction/rs_marshalling_helper.h b/rosen/modules/render_service_base/include/transaction/rs_marshalling_helper.h index 4cdc7d5b08..4219a12469 100644 --- a/rosen/modules/render_service_base/include/transaction/rs_marshalling_helper.h +++ b/rosen/modules/render_service_base/include/transaction/rs_marshalling_helper.h @@ -52,6 +52,7 @@ class RSPath; class RSLinearGradientBlurPara; class MotionBlurParam; class EmitterUpdater; +class ParticleNoiseField; template class RenderParticleParaType; class EmitterConfig; @@ -234,6 +235,7 @@ public: DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) + DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) DECLARE_FUNCTION_OVERLOAD(std::shared_ptr) diff --git a/rosen/modules/render_service_base/include/transaction/rs_render_service_client.h b/rosen/modules/render_service_base/include/transaction/rs_render_service_client.h index eea96a341c..6dc66cb7b5 100644 --- a/rosen/modules/render_service_base/include/transaction/rs_render_service_client.h +++ b/rosen/modules/render_service_base/include/transaction/rs_render_service_client.h @@ -122,6 +122,8 @@ public: uint64_t id = 0, NodeId windowNodeId = 0); + std::shared_ptr CreatePixelMapFromSurfaceId(uint64_t surfaceid, const Rect &srcRect); + bool TakeSurfaceCapture( NodeId id, std::shared_ptr callback, float scaleX, float scaleY, SurfaceCaptureType surfaceCaptureType = SurfaceCaptureType::DEFAULT_CAPTURE, bool isSync = false); diff --git a/rosen/modules/render_service_base/src/animation/rs_particle_noise_field.cpp b/rosen/modules/render_service_base/src/animation/rs_particle_noise_field.cpp new file mode 100644 index 0000000000..d2cbe93ba2 --- /dev/null +++ b/rosen/modules/render_service_base/src/animation/rs_particle_noise_field.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2024-2024 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 "animation/rs_particle_noise_field.h" + +namespace OHOS { +namespace Rosen { +const float EPSILON = 1e-3; +const float HALF = 0.5f; +bool ParticleNoiseField::isPointInField( + const Vector2f& point, const ShapeType& fieldShape, const Vector2f& fieldCenter, float width, float height) +{ + if (fieldShape == ShapeType::RECT) { + return (point.x_ > fieldCenter_.x_ - width * HALF && point.x_ < fieldCenter_.x_ + width * HALF && + point.y_ >= fieldCenter_.y_ - height * HALF && point.y_ < fieldCenter_.y_ + height * HALF); + } else { + double normX = (point.x_ - fieldCenter_.x_) * (point.x_ - fieldCenter_.x_); + double normY = (point.y_ - fieldCenter_.y_) * (point.y_ - fieldCenter_.y_); + return (normX / (width * HALF * width * HALF) + normY / (height * HALF * height * HALF) <= 1.0); + } + return false; +} + +float ParticleNoiseField::calculateEllipseEdgeDistance(const Vector2f& direction) +{ + // direction is the direction vector from the center to the particle location. + // Check whether the direction is zero vector. + if (direction.x_ == 0 && direction.y_ == 0) { + return 0; + } + // Implicit equation of the ellipse edge: (x/a)^2 + (y/b)^2 = 1 + // Solve the equation and find the edge point that is the same as the direction of the direction vector. + // Because the direction vector may not be aligned with the elliptic axis, the parameter equation and elliptic + // equation are used together to solve the problem. + // The parameter equation is x = cx + t * dx, y = cy + t * dy. + // Substituting the parameter equation into the elliptic equation to solve t + float t = std::sqrt(1 / ((direction.x_ * direction.x_) / (fieldSize_.x_ * fieldSize_.x_ / 4) + + (direction.y_ * direction.y_) / (fieldSize_.y_ * fieldSize_.y_ / 4))); + return t; // t is the distance from the center point to the edge. +} + +float ParticleNoiseField::calculateDistanceToRectangleEdge( + const Vector2f& position, const Vector2f& direction, const Vector2f& center, const Vector2f& size) +{ + if (direction.x_ == 0 && direction.y_ == 0) { + return 0.0f; + } + // Calculates the four boundaries of a rectangle. + float left = center.x_ - size.x_ * HALF; + float right = center.x_ + size.x_ * HALF; + float top = center.y_ - size.y_ * HALF; + float bottom = center.y_ + size.y_ * HALF; + // Calculate the time required for reaching each boundary. + float tLeft = (left - position.x_) / direction.x_; + float tRight = (right - position.x_) / direction.x_; + float tTop = (top - position.y_) / direction.y_; + float tBottom = (bottom - position.y_) / direction.y_; + + // Particles advance to the boundary only if t is a positive number. + std::vector times; + if (tLeft > 0) + times.push_back(tLeft); + if (tRight > 0) + times.push_back(tRight); + if (tTop > 0) + times.push_back(tTop); + if (tBottom > 0) + times.push_back(tBottom); + + if (times.empty()) { + return 0.0f; + } + // The smallest value of t, which is the first time the particle will reach the boundary. + float tEdge = *std::min_element(times.begin(), times.end()); + // Calculates the distance to the border. + float distance = std::sqrt(std::pow(tEdge * direction.x_, 2) + std::pow(tEdge * direction.y_, 2)); + return distance; +} + +Vector2f ParticleNoiseField::ApplyField(const Vector2f& position) +{ + // If the position is in the field, calculate the field force. + Vector2f direction = position - fieldCenter_; + float distance = direction.GetLength(); + float forceMagnitude = fieldStrength_; + if (isPointInField(position, fieldShape_, fieldCenter_, fieldSize_.x_, fieldSize_.y_)) { + if (fieldFeather_ > 0) { + float edgeDistance = fieldSize_.x_ * HALF; + if (fieldShape_ == ShapeType::RECT) { + edgeDistance = calculateDistanceToRectangleEdge(position, direction, fieldCenter_, fieldSize_); + } else if (fieldShape_ == ShapeType::ELLIPSE) { + edgeDistance = calculateEllipseEdgeDistance(direction); + } + if (edgeDistance != 0) { + forceMagnitude *= (1.0f - (float)fieldFeather_ / 100.0f * (distance / edgeDistance)); + } + } + Vector2f force = direction.Normalized() * forceMagnitude; + return force; + } + return Vector2f { 0.f, 0.f }; +} + +Vector2f ParticleNoiseField::ApplyCurlNoise(const Vector2f& position) +{ + if (isPointInField(position, fieldShape_, fieldCenter_, fieldSize_.x_, fieldSize_.y_)) { + PerlinNoise2D noise(noiseScale_, noiseFrequency_, noiseAmplitude_); + return noise.curl(position.x_, position.y_); + } + return Vector2f { 0.f, 0.f }; +} + +float PerlinNoise2D::fade(float t) +{ + // Fade function as defined by Ken Perlin: 6t^5 - 15t^4 + 10t^3 + return t * t * t * (t * (t * 6 - 15) + 10); +} + +float PerlinNoise2D::lerp(float t, float a, float b) +{ + // Linear interpolate between a and b + return a + t * (b - a); +} + +float PerlinNoise2D::grad(int hash, float x, float y) +{ + // Convert low 4 bits of hash code into 12 gradient directions + int h = hash & 15; + double u = h < 8 ? x : y; + double v = h < 4 ? y : h == 12 || h == 14 ? x : 0; + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); // h & 2 check the h's second least bit +} + +PerlinNoise2D::PerlinNoise2D(float noiseScale, float noiseFrequency, float noiseAmplitude) +{ + noiseScale_ = noiseScale; + noiseFrequency_ = noiseFrequency; + noiseAmplitude_ = noiseAmplitude; + // Initialize permutation vector with values from 0 to 255 + p.resize(256); // 256 is the vector size + std::iota(p.begin(), p.end(), 0); + + // Shuffle using a default random engine + std::default_random_engine engine; + std::shuffle(p.begin(), p.end(), engine); + + // Duplicate the permutation vector + p.insert(p.end(), p.begin(), p.end()); +} + +float PerlinNoise2D::noise(float x, float y) +{ + x *= (noiseFrequency_ / noiseScale_); + y *= (noiseFrequency_ / noiseScale_); + // Find the unit square that contains the point + int X = (int)floor(x) & 255; + int Y = (int)floor(y) & 255; + + // Find relative x, y of point in square + x -= floor(x); + y -= floor(y); + + // Compute fade curves for each of x, y + float u = fade(x); + float v = fade(y); + + // Hash coordinates of the 4 square corners + int A = p[X] + Y; + int AA = p[A]; + int AB = p[A + 1]; + int B = p[X + 1] + Y; + int BA = p[B]; + int BB = p[B + 1]; + + // And add blended results from the 4 corners of the square + float res = lerp(v, lerp(u, grad(p[AA], x, y), grad(p[BA], x - 1, y)), + lerp(u, grad(p[AB], x, y - 1), grad(p[BB], x - 1, y - 1))); + + return (noiseFrequency_ * noiseScale_) * (res + 1.f) / 2.f; // Normalize the result +} + +// In the two-dimensional mode, curl actually returns a vector instead of a scalar. +Vector2f PerlinNoise2D::curl(float x, float y) +{ + // Calculate the partial derivative of the noise field. + float noise_dx = noise(x + EPSILON, y) - noise(x - EPSILON, y); + float noise_dy = noise(x, y + EPSILON) - noise(x, y - EPSILON); + + // The result of the two-dimensional curl is the vector obtained by rotating the gradient by 90 degrees. + // Assume that Curl has a value only in the Z component (rotation in the two-dimensional plane). + float curlx = -noise_dy / (2 * EPSILON); + float curly = noise_dx / (2 * EPSILON); + + return Vector2f(curlx, curly); +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/rosen/modules/render_service_base/src/animation/rs_render_particle.cpp b/rosen/modules/render_service_base/src/animation/rs_render_particle.cpp index d11d0e3329..0918443e09 100644 --- a/rosen/modules/render_service_base/src/animation/rs_render_particle.cpp +++ b/rosen/modules/render_service_base/src/animation/rs_render_particle.cpp @@ -25,6 +25,7 @@ namespace OHOS { namespace Rosen { constexpr float DEGREE_TO_RADIAN = M_PI / 180; constexpr int RAND_PRECISION = 10000; +constexpr float SIGMA = 3.f; int ParticleRenderParams::GetEmitRate() const { @@ -53,16 +54,16 @@ int32_t ParticleRenderParams::GetParticleCount() const int64_t ParticleRenderParams::GetLifeTimeStartValue() const { - if (emitterConfig_.lifeTime_.start_ > std::numeric_limits::max() / NS_PER_MS) { - return std::numeric_limits::max(); + if (emitterConfig_.lifeTime_.start_ > std::numeric_limits::max() / NS_PER_MS) { + return std::numeric_limits::max(); } return emitterConfig_.lifeTime_.start_ * NS_PER_MS; } int64_t ParticleRenderParams::GetLifeTimeEndValue() const { - if (emitterConfig_.lifeTime_.end_ > std::numeric_limits::max() / NS_PER_MS) { - return std::numeric_limits::max(); + if (emitterConfig_.lifeTime_.end_ > std::numeric_limits::max() / NS_PER_MS) { + return std::numeric_limits::max(); } return emitterConfig_.lifeTime_.end_ * NS_PER_MS; } @@ -167,6 +168,11 @@ const Color& ParticleRenderParams::GetColorEndValue() return color_.colorVal_.end_; } +const DistributionType& ParticleRenderParams::GetColorDistribution() +{ + return color_.distribution_; +} + const ParticleUpdator& ParticleRenderParams::GetColorUpdator() { return color_.updator_; @@ -652,12 +658,7 @@ void RSRenderParticle::InitProperty() particleType_ = particleParams_->GetParticleType(); if (particleType_ == ParticleType::POINTS) { - float colorRandomValue = GetRandomValue(0.0f, 1.0f); - color_ = Lerp(particleParams_->GetColorStartValue(), particleParams_->GetColorEndValue(), colorRandomValue); - redSpeed_ = GetRandomValue(particleParams_->GetRedRandomStart(), particleParams_->GetRedRandomEnd()); - greenSpeed_ = GetRandomValue(particleParams_->GetGreenRandomStart(), particleParams_->GetGreenRandomEnd()); - blueSpeed_ = GetRandomValue(particleParams_->GetBlueRandomStart(), particleParams_->GetBlueRandomEnd()); - alphaSpeed_ = GetRandomValue(particleParams_->GetAlphaRandomStart(), particleParams_->GetAlphaRandomEnd()); + SetColor(); radius_ = particleParams_->GetParticleRadius(); } else if (particleType_ == ParticleType::IMAGES) { image_ = particleParams_->GetParticleImage(); @@ -703,6 +704,36 @@ float RSRenderParticle::GetRandomValue(float min, float max) return rand_float; } +void RSRenderParticle::SetColor() +{ + if (particleParams_->GetColorDistribution() == DistributionType::GAUSSIAN) { + color_.SetRed(GenerateColorComponent(0.0, SIGMA)); + color_.SetGreen(GenerateColorComponent(0.0, SIGMA)); + color_.SetBlue(GenerateColorComponent(0.0, SIGMA)); + } else { + float colorRandomValue = GetRandomValue(0.0f, 1.0f); + color_ = Lerp(particleParams_->GetColorStartValue(), particleParams_->GetColorEndValue(), colorRandomValue); + } + redSpeed_ = GetRandomValue(particleParams_->GetRedRandomStart(), particleParams_->GetRedRandomEnd()); + greenSpeed_ = GetRandomValue(particleParams_->GetGreenRandomStart(), particleParams_->GetGreenRandomEnd()); + blueSpeed_ = GetRandomValue(particleParams_->GetBlueRandomStart(), particleParams_->GetBlueRandomEnd()); + alphaSpeed_ = GetRandomValue(particleParams_->GetAlphaRandomStart(), particleParams_->GetAlphaRandomEnd()); +} + +// Generate color components that follow normal distribution +int RSRenderParticle::GenerateColorComponent(double mean, double stddev) +{ + // Creates a random number engine and a normal distribution object. + std::random_device rd; + std::mt19937 gen(rd()); + std::normal_distribution<> dis(mean, stddev); + + double number = dis(gen); + int component = static_cast(std::round(std::abs(number))); + component = std::max(0, std::min(component, 255)); // 255 is RGB Component max. + return component; +} + Vector2f RSRenderParticle::CalculateParticlePosition( const ShapeType& emitShape, const Vector2f& position, const Vector2f& emitSize) { @@ -737,15 +768,5 @@ Vector2f RSRenderParticle::CalculateParticlePosition( return Vector2f { positionX, positionY }; } -Color RSRenderParticle::Lerp(const Color& start, const Color& end, float t) -{ - Color result; - result.SetRed(start.GetRed() + static_cast(std::round((end.GetRed() - start.GetRed()) * t))); - result.SetGreen(start.GetGreen() + static_cast(std::round((end.GetGreen() - start.GetGreen()) * t))); - result.SetBlue(start.GetBlue() + static_cast(std::round((end.GetBlue() - start.GetBlue()) * t))); - result.SetAlpha(start.GetAlpha() + static_cast(std::round((end.GetAlpha() - start.GetAlpha()) * t))); - return result; -} - } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/src/animation/rs_render_particle_animation.cpp b/rosen/modules/render_service_base/src/animation/rs_render_particle_animation.cpp index d6b4d2e734..69452ebf9b 100644 --- a/rosen/modules/render_service_base/src/animation/rs_render_particle_animation.cpp +++ b/rosen/modules/render_service_base/src/animation/rs_render_particle_animation.cpp @@ -17,12 +17,13 @@ #include +#include "rs_profiler.h" + #include "animation/rs_value_estimator.h" #include "command/rs_animation_command.h" #include "common/rs_optional_trace.h" #include "platform/common/rs_log.h" #include "transaction/rs_marshalling_helper.h" -#include "rs_profiler.h" namespace OHOS { namespace Rosen { @@ -56,6 +57,10 @@ bool RSRenderParticleAnimation::Animate(int64_t time) int64_t deltaTime = time - animationFraction_.GetLastFrameTime(); animationFraction_.SetLastFrameTime(time); if (particleSystem_ != nullptr) { + auto particleNoiseField = target->GetRenderProperties().GetParticleNoiseField(); + if (particleNoiseField) { + UpdateNoiseField(particleNoiseField); + } particleSystem_->Emit(deltaTime, renderParticleVector_.renderParticleVector_); particleSystem_->UpdateParticle(deltaTime, renderParticleVector_.renderParticleVector_); } @@ -97,6 +102,17 @@ void RSRenderParticleAnimation::UpdateEmitter(const std::shared_ptr& particleNoiseField) +{ + if (particleNoiseField == nullptr) { + return; + } else if (particleNoiseField_ != nullptr && *particleNoiseField_ == *particleNoiseField) { + return; + } + particleNoiseField_ = particleNoiseField; + particleSystem_->UpdateNoiseField(particleNoiseField); +} + void RSRenderParticleAnimation::OnAttach() { auto target = GetTarget(); diff --git a/rosen/modules/render_service_base/src/animation/rs_render_particle_effector.cpp b/rosen/modules/render_service_base/src/animation/rs_render_particle_effector.cpp index 55ae64456f..f16345d08f 100644 --- a/rosen/modules/render_service_base/src/animation/rs_render_particle_effector.cpp +++ b/rosen/modules/render_service_base/src/animation/rs_render_particle_effector.cpp @@ -47,10 +47,9 @@ Vector4 RSRenderParticleEffector::CalculateColorInt(const std::shared_p return colorInt; } -float RSRenderParticleEffector::UpdateCurveValue( - const std::vector>>& valChangeOverLife, int64_t activeTime) +void RSRenderParticleEffector::UpdateCurveValue( + float& value, const std::vector>>& valChangeOverLife, int64_t activeTime) { - float value = 0.f; for (size_t i = 0; i < valChangeOverLife.size(); i++) { int startTime = valChangeOverLife[i]->startMillis_; int endTime = valChangeOverLife[i]->endMillis_; @@ -62,46 +61,37 @@ float RSRenderParticleEffector::UpdateCurveValue( #ifdef ENABLE_RUST value = generate_value(startValue, endValue, startTime, endTime, activeTime); #else - if (endTime - startTime != 0) { + if (endTime - startTime > 0) { float t = static_cast(activeTime - startTime) / static_cast(endTime - startTime); auto& interpolator = valChangeOverLife[i]->interpolator_; t = (interpolator != nullptr) ? interpolator->Interpolate(t) : t; value = startValue * (1.0f - t) + endValue * t; - } else { - value = startValue; } #endif break; } - return value; } -Color RSRenderParticleEffector::UpdateColorCurveValue( - const std::vector>>& valChangeOverLife, int64_t activeTime) +void RSRenderParticleEffector::UpdateColorCurveValue( + Color& color, const std::vector>>& valChangeOverLife, int64_t activeTime) { - Color color; for (size_t i = 0; i < valChangeOverLife.size(); i++) { int startTime = valChangeOverLife[i]->startMillis_; int endTime = valChangeOverLife[i]->endMillis_; if (activeTime < startTime || activeTime > endTime) { continue; } - Color startValue = valChangeOverLife[i]->fromValue_; - if (endTime - startTime != 0) { + if (endTime - startTime > 0) { + Color startValue = valChangeOverLife[i]->fromValue_; Color endValue = valChangeOverLife[i]->toValue_; float t = static_cast(activeTime - startTime) / static_cast(endTime - startTime); auto& interpolator = valChangeOverLife[i]->interpolator_; t = (interpolator != nullptr) ? interpolator->Interpolate(t) : t; - startValue *= (1.0f - t); - endValue *= t; - color = startValue + endValue; - } else { - color = startValue; + color = RSRenderParticle::Lerp(startValue, endValue, t); } - color = Color(color.AsArgbInt()); + color = Color(color.AsRgbaInt()); break; } - return color; } void RSRenderParticleEffector::UpdateColor(const std::shared_ptr& particle, float deltaTime) @@ -124,7 +114,7 @@ void RSRenderParticleEffector::UpdateColor(const std::shared_ptrGetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetColorChangeOverLife(); - color = UpdateColorCurveValue(valChangeOverLife, activeTime); + UpdateColorCurveValue(color, valChangeOverLife, activeTime); } particle->SetColor(color); } @@ -147,7 +137,7 @@ void RSRenderParticleEffector::UpdateOpacity(const std::shared_ptrGetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetOpacityChangeOverLife(); - opacity = UpdateCurveValue(valChangeOverLife, activeTime); + UpdateCurveValue(opacity, valChangeOverLife, activeTime); } particle->SetOpacity(opacity); } @@ -166,7 +156,7 @@ void RSRenderParticleEffector::UpdateScale(const std::shared_ptrGetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetScaleChangeOverLife(); - scale = UpdateCurveValue(valChangeOverLife, activeTime); + UpdateCurveValue(scale, valChangeOverLife, activeTime); } particle->SetScale(scale); } @@ -181,7 +171,7 @@ void RSRenderParticleEffector::UpdateSpin(const std::shared_ptrGetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetSpinChangeOverLife(); - spin = UpdateCurveValue(valChangeOverLife, activeTime); + UpdateCurveValue(spin, valChangeOverLife, activeTime); } particle->SetSpin(spin); } @@ -197,7 +187,7 @@ void RSRenderParticleEffector::UpdateAccelerationAngle( } else if (acceAngleUpdator == ParticleUpdator::CURVE) { int64_t activeTime = particle->GetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetAcceAngChangeOverLife(); - accelerationAngle = UpdateCurveValue(valChangeOverLife, activeTime); + UpdateCurveValue(accelerationAngle, valChangeOverLife, activeTime); } particle->SetAccelerationAngle(accelerationAngle); } @@ -213,18 +203,26 @@ void RSRenderParticleEffector::UpdateAccelerationValue( } else if (acceValueUpdator == ParticleUpdator::CURVE) { int64_t activeTime = particle->GetActiveTime() / NS_PER_MS; auto& valChangeOverLife = particle->GetAcceValChangeOverLife(); - accelerationValue = UpdateCurveValue(valChangeOverLife, activeTime); + UpdateCurveValue(accelerationValue, valChangeOverLife, activeTime); } particle->SetAccelerationValue(accelerationValue); } -void RSRenderParticleEffector::UpdatePosition(const std::shared_ptr& particle, float deltaTime) +void RSRenderParticleEffector::UpdatePosition(const std::shared_ptr& particle, + const std::shared_ptr& particleNoiseField, float deltaTime) { + auto position = particle->GetPosition(); + auto fieldForce = Vector2f(0.f, 0.f); + if (particleNoiseField != nullptr) { + fieldForce += particleNoiseField->ApplyField(position); + fieldForce += particleNoiseField->ApplyCurlNoise(position); + } auto accelerationValue = particle->GetAccelerationValue(); auto accelerationAngle = particle->GetAccelerationAngle(); accelerationAngle *= DEGREE_TO_RADIAN; auto acceleration = Vector2f { accelerationValue * std::cos(accelerationAngle), accelerationValue * std::sin(accelerationAngle) }; + acceleration += fieldForce; particle->SetAcceleration(acceleration); Vector2f velocity = particle->GetVelocity(); @@ -234,7 +232,6 @@ void RSRenderParticleEffector::UpdatePosition(const std::shared_ptrSetVelocity(velocity); } - Vector2f position = particle->GetPosition(); if (!(ROSEN_EQ(velocity.x_, 0.f) && ROSEN_EQ(velocity.y_, 0.f))) { position.x_ += velocity.x_ * deltaTime; position.y_ += velocity.y_ * deltaTime; @@ -250,7 +247,8 @@ void RSRenderParticleEffector::UpdateActiveTime(const std::shared_ptr& particle, int64_t deltaTime) +void RSRenderParticleEffector::Update(const std::shared_ptr& particle, + const std::shared_ptr& particleNoiseField, int64_t deltaTime) { float dt = static_cast(deltaTime) / NS_TO_S; UpdateAccelerationValue(particle, dt); @@ -259,7 +257,7 @@ void RSRenderParticleEffector::Update(const std::shared_ptr& p UpdateOpacity(particle, dt); UpdateScale(particle, dt); UpdateSpin(particle, dt); - UpdatePosition(particle, dt); + UpdatePosition(particle, particleNoiseField, dt); UpdateActiveTime(particle, deltaTime); } diff --git a/rosen/modules/render_service_base/src/animation/rs_render_particle_system.cpp b/rosen/modules/render_service_base/src/animation/rs_render_particle_system.cpp index 522779ca8b..f21741fbf9 100644 --- a/rosen/modules/render_service_base/src/animation/rs_render_particle_system.cpp +++ b/rosen/modules/render_service_base/src/animation/rs_render_particle_system.cpp @@ -60,7 +60,7 @@ void RSRenderParticleSystem::UpdateParticle( if ((*it) == nullptr || !(*it)->IsAlive()) { it = activeParticles.erase(it); } else { - Update((*it), deltaTime); + Update((*it), particleNoiseField_, deltaTime); ++it; } } @@ -86,5 +86,9 @@ void RSRenderParticleSystem::UpdateEmitter( emitters_[emitterIndex]->UpdateEmitter(position, emitSize, emitRate); } +void RSRenderParticleSystem::UpdateNoiseField(const std::shared_ptr& particleNoiseField) +{ + particleNoiseField_ = particleNoiseField; +} } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/src/common/rs_background_thread.cpp b/rosen/modules/render_service_base/src/common/rs_background_thread.cpp index 4227b66500..71eba868c6 100644 --- a/rosen/modules/render_service_base/src/common/rs_background_thread.cpp +++ b/rosen/modules/render_service_base/src/common/rs_background_thread.cpp @@ -55,6 +55,14 @@ void RSBackgroundThread::PostTask(const std::function& task) handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE); } } + +void RSBackgroundThread::PostSyncTask(const std::function& task) +{ + if (handler_) { + handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE); + } +} + #if defined(RS_ENABLE_UNI_RENDER) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)) #ifdef RS_ENABLE_GL void RSBackgroundThread::CreateShareEglContext() @@ -134,7 +142,7 @@ std::shared_ptr RSBackgroundThread::CreateShareGPUContext() return nullptr; } -void RSBackgroundThread::SetGrResourceFinishFlag(bool resourceFinish) +void RSBackgroundThread::SetGrResourceFinishFlag(const bool& resourceFinish) { resourceFinish_ = resourceFinish; } diff --git a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp index 96e02403a4..f1f70cdd56 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp @@ -16,11 +16,13 @@ #include "drawable/rs_drawable.h" #include + #include "drawable/rs_misc_drawable.h" #include "drawable/rs_property_drawable.h" #include "drawable/rs_property_drawable_background.h" #include "drawable/rs_property_drawable_foreground.h" #include "pipeline/rs_render_node.h" +#include "pipeline/rs_surface_render_node.h" namespace OHOS::Rosen { namespace { @@ -29,7 +31,7 @@ using namespace DrawableV2; // NOTE: This LUT should always the same size and order as RSModifierType // key = RSModifierType, value = RSDrawableSlot constexpr int DIRTY_LUT_SIZE = static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE); -static const std::array g_propertyToDrawableLut = { +static constexpr std::array g_propertyToDrawableLut = { RSDrawableSlot::INVALID, // INVALID RSDrawableSlot::CLIP_TO_BOUNDS, // BOUNDS RSDrawableSlot::FRAME_OFFSET, // FRAME @@ -63,9 +65,9 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::BORDER, // BORDER_COLOR RSDrawableSlot::BORDER, // BORDER_WIDTH RSDrawableSlot::BORDER, // BORDER_STYLE - RSDrawableSlot::FOREGROUND_FILTER, // FILTER + RSDrawableSlot::COMPOSITING_FILTER, // FILTER RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_FILTER - RSDrawableSlot::FOREGROUND_FILTER, // LINEAR_GRADIENT_BLUR_PARA + RSDrawableSlot::COMPOSITING_FILTER, // LINEAR_GRADIENT_BLUR_PARA RSDrawableSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_RATE RSDrawableSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_DEGREE RSDrawableSlot::FRAME_OFFSET, // FRAME_GRAVITY @@ -117,7 +119,9 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::POINT_LIGHT, // ILLUMINATED_TYPE RSDrawableSlot::POINT_LIGHT, // BLOOM RSDrawableSlot::PARTICLE_EFFECT, // PARTICLE_EMITTER_UPDATER - RSDrawableSlot::INVALID, // FOREGROUND_EFFECT_RADIUS + RSDrawableSlot::PARTICLE_EFFECT, // PARTICLE_NOISE_FIELD + RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_EFFECT_RADIUS + RSDrawableSlot::INVALID, // MOTION_BLUR_PARA RSDrawableSlot::DYNAMIC_DIM, // DYNAMIC_DIM RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_SATURATION @@ -126,13 +130,13 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_COLOR_MODE RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS_X RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS_Y - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_RADIUS - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_SATURATION - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_BRIGHTNESS - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_MASK_COLOR - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_COLOR_MODE - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_RADIUS_X - RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_BLUR_RADIUS_Y + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_SATURATION + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_BRIGHTNESS + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_MASK_COLOR + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_COLOR_MODE + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_X + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_Y RSDrawableSlot::INVALID, // CUSTOM RSDrawableSlot::INVALID, // EXTENDED RSDrawableSlot::TRANSITION, // TRANSITION @@ -147,6 +151,21 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::CHILDREN, // CHILDREN }; +// Check if g_propertyToDrawableLut size match and is fully initialized (the last element should not be default value) +static_assert(g_propertyToDrawableLut.size() == static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE)); +static_assert(g_propertyToDrawableLut.back() != RSDrawableSlot {}); + +// Randomly check some LUT index and value +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::USE_EFFECT)] == RSDrawableSlot::USE_EFFECT); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::FOREGROUND_COLOR)] == RSDrawableSlot::FOREGROUND_COLOR); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::CLIP_TO_FRAME)] == RSDrawableSlot::CLIP_TO_FRAME); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::USE_SHADOW_BATCHING)] == RSDrawableSlot::CHILDREN); +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::TRANSITION)] == RSDrawableSlot::TRANSITION); +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::CHILDREN)] == RSDrawableSlot::CHILDREN); + template static inline RSDrawable::Ptr ModifierGenerator(const RSRenderNode& node) { @@ -164,6 +183,7 @@ static const std::array g_drawableGenerator ModifierGenerator, // TRANSITION, RSEnvFGColorDrawable::OnGenerate, // ENV_FOREGROUND_COLOR, RSShadowDrawable::OnGenerate, // SHADOW, + RSForegroundFilterDrawable::OnGenerate, // FOREGROUND_FILTER RSOutlineDrawable::OnGenerate, // OUTLINE, // BG properties in Bounds Clip @@ -190,15 +210,15 @@ static const std::array g_drawableGenerator nullptr, // RESTORE_FRAME, // FG properties in Bounds clip - nullptr, // FG_SAVE_BOUNDS, - nullptr, // FG_CLIP_TO_BOUNDS, - RSBinarizationDrawable::OnGenerate, // BINARIZATION, - RSColorFilterDrawable::OnGenerate, // COLOR_FILTER, - RSLightUpEffectDrawable::OnGenerate, // LIGHT_UP_EFFECT, - RSDynamicDimDrawable::OnGenerate, // DYNAMIC_DIM, - RSForegroundFilterDrawable::OnGenerate, // FOREGROUND_FILTER, - RSForegroundColorDrawable::OnGenerate, // FOREGROUND_COLOR, - nullptr, // FG_RESTORE_BOUNDS, + nullptr, // FG_SAVE_BOUNDS, + nullptr, // FG_CLIP_TO_BOUNDS, + RSBinarizationDrawable::OnGenerate, // BINARIZATION, + RSColorFilterDrawable::OnGenerate, // COLOR_FILTER, + RSLightUpEffectDrawable::OnGenerate, // LIGHT_UP_EFFECT, + RSDynamicDimDrawable::OnGenerate, // DYNAMIC_DIM, + RSCompositingFilterDrawable::OnGenerate, // COMPOSITING_FILTER, + RSForegroundColorDrawable::OnGenerate, // FOREGROUND_COLOR, + nullptr, // FG_RESTORE_BOUNDS, // No clip (unless ClipToBounds is set) RSPointLightDrawable::OnGenerate, // POINT_LIGHT, @@ -208,8 +228,9 @@ static const std::array g_drawableGenerator RSPixelStretchDrawable::OnGenerate, // PIXEL_STRETCH, // Restore state - RSEndBlendModeDrawable::OnGenerate, // RESTORE_BLEND_MODE, - nullptr, // RESTORE_ALL, + RSEndBlendModeDrawable::OnGenerate, // RESTORE_BLEND_MODE, + RSForegroundFilterRestoreDrawable::OnGenerate, // RESTORE_FOREGROUND_FILTER + nullptr, // RESTORE_ALL, }; enum DrawableVecStatus : uint8_t { @@ -241,9 +262,11 @@ static uint8_t CalculateDrawableVecStatus(RSRenderNode& node, const RSDrawable:: uint8_t result = 0; auto& properties = node.GetRenderProperties(); - // color blend mode has implicit dependency on clipToBounds - if (properties.GetClipToBounds() || properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || - properties.GetColorBlendMode() != static_cast(RSColorBlendMode::NONE)) { + // ClipToBounds if either 1. is surface node, 2. has explicit clip properties, 3. has blend mode + bool shouldClipToBounds = node.IsInstanceOf() || properties.GetClipToBounds() || + properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || + properties.GetColorBlendMode() != static_cast(RSColorBlendMode::NONE); + if (shouldClipToBounds) { result |= DrawableVecStatus::CLIP_TO_BOUNDS; } @@ -301,6 +324,7 @@ inline static void SaveRestoreHelper(RSDrawable::Vec& drawableVec, RSDrawableSlo static void OptimizeBoundsSaveRestore(RSRenderNode& node, RSDrawable::Vec& drawableVec, uint8_t flags) { + // Erase existing save/clip/restore before re-generating constexpr static std::array boundsSlotsToErase = { RSDrawableSlot::BG_SAVE_BOUNDS, RSDrawableSlot::CLIP_TO_BOUNDS, @@ -309,8 +333,6 @@ static void OptimizeBoundsSaveRestore(RSRenderNode& node, RSDrawable::Vec& drawa RSDrawableSlot::FG_CLIP_TO_BOUNDS, RSDrawableSlot::FG_RESTORE_BOUNDS, }; - - // Erase existing save/clip/restore before re-generating for (auto& slot : boundsSlotsToErase) { drawableVec[static_cast(slot)] = nullptr; } @@ -422,34 +444,44 @@ std::unordered_set RSDrawable::CalculateDirtySlots( } // Step 1.2: expand dirty slots by rules - // planning: border etc. should be updated when border radius changed - if (dirtySlots.count(RSDrawableSlot::FRAME_OFFSET)) { - if (drawableVec[static_cast(RSDrawableSlot::CLIP_TO_FRAME)]) { - dirtySlots.emplace(RSDrawableSlot::CLIP_TO_FRAME); - } - } - - // Step 1.3: if bounds changed, every existing drawable needs to be updated - if (dirtyTypes.test(static_cast(RSModifierType::BOUNDS))) { - for (size_t i = 0; i < drawableVec.size(); i++) { - if (drawableVec[i]) { - dirtySlots.emplace(static_cast(i)); + // if bounds or cornerRadius changed, mark affected drawables as dirty + static constexpr std::array boundsDirtyTypes = { + RSDrawableSlot::MASK, + RSDrawableSlot::SHADOW, + RSDrawableSlot::OUTLINE, + RSDrawableSlot::CLIP_TO_BOUNDS, + RSDrawableSlot::BACKGROUND_COLOR, + RSDrawableSlot::BACKGROUND_SHADER, + RSDrawableSlot::BACKGROUND_IMAGE, + RSDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY, + RSDrawableSlot::FG_CLIP_TO_BOUNDS, + RSDrawableSlot::FOREGROUND_COLOR, + RSDrawableSlot::POINT_LIGHT, + RSDrawableSlot::BORDER, + RSDrawableSlot::PIXEL_STRETCH, + }; + if (dirtyTypes.test(static_cast(RSModifierType::BOUNDS)) || + dirtyTypes.test(static_cast(RSModifierType::CORNER_RADIUS))) { + for (auto slot : boundsDirtyTypes) { + if (drawableVec[static_cast(slot)]) { + dirtySlots.emplace(slot); } } } - // Step 1.4: if corner radius changed, update border and outline - if (dirtyTypes.test(static_cast(RSModifierType::CORNER_RADIUS))) { - // border may should be updated with corner radius - if (drawableVec[static_cast(RSDrawableSlot::BORDER)]) { - dirtySlots.emplace(RSDrawableSlot::BORDER); + // if frame changed, mark affected drawables as dirty + if (dirtySlots.count(RSDrawableSlot::FRAME_OFFSET)) { + if (drawableVec[static_cast(RSDrawableSlot::CLIP_TO_FRAME)]) { + dirtySlots.emplace(RSDrawableSlot::CLIP_TO_FRAME); } - - if (drawableVec[static_cast(RSDrawableSlot::OUTLINE)]) { - dirtySlots.emplace(RSDrawableSlot::OUTLINE); + if (drawableVec[static_cast(RSDrawableSlot::FOREGROUND_FILTER)]) { + dirtySlots.emplace(RSDrawableSlot::FOREGROUND_FILTER); } } + if (dirtySlots.count(RSDrawableSlot::FOREGROUND_FILTER)) { + dirtySlots.emplace(RSDrawableSlot::RESTORE_FOREGROUND_FILTER); + } return dirtySlots; } diff --git a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp index a26a80eb47..09a2ad04d2 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp @@ -45,7 +45,7 @@ bool RSChildrenDrawable::OnUpdate(const RSRenderNode& node) continue; } if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(child)) { - childDrawable->SetSkipShadow(false); + childDrawable->SetSkip(SkipType::NONE); stagingChildrenDrawableVec_.push_back(std::move(childDrawable)); } } @@ -63,7 +63,7 @@ bool RSChildrenDrawable::OnUpdate(const RSRenderNode& node) stagingChildrenDrawableVec_.push_back(std::move(shadowDrawable)); } if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(child)) { - childDrawable->SetSkipShadow(true); + childDrawable->SetSkip(SkipType::SKIP_SHADOW); pendingChildren.push_back(std::move(childDrawable)); } } @@ -107,7 +107,7 @@ bool RSChildrenDrawable::OnSharedTransition(const RSRenderNode::SharedPtr& node) // for higher hierarchy node, we add paired node (lower in hierarchy) first, then add it if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(pairedNode)) { // NOTE: skip shared-transition shadow for now - childDrawable->SetSkipShadow(true); + childDrawable->SetSkip(SkipType::SKIP_SHADOW); stagingChildrenDrawableVec_.push_back(std::move(childDrawable)); } } @@ -306,7 +306,7 @@ RSDrawable::Ptr RSEndBlendModeDrawable::OnGenerate(const RSRenderNode& node) return nullptr; } - return std::make_shared(); + return std::make_shared(properties.GetColorBlendApplyType()); }; bool RSEndBlendModeDrawable::OnUpdate(const RSRenderNode& node) @@ -318,14 +318,27 @@ bool RSEndBlendModeDrawable::OnUpdate(const RSRenderNode& node) return false; } + stagingBlendApplyType_ = properties.GetColorBlendApplyType(); + needSync_ = true; + return true; } +void RSEndBlendModeDrawable::OnSync() +{ + if (needSync_ == false) { + return; + } + blendApplyType_ = stagingBlendApplyType_; + needSync_ = false; +} + Drawing::RecordingCanvas::DrawFunc RSEndBlendModeDrawable::CreateDrawFunc() const { - return [](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { auto paintFilterCanvas = static_cast(canvas); - RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas); + RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas, ptr->blendApplyType_); }; } diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp index 5ce3a6979c..8dd3a50d85 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp @@ -153,6 +153,7 @@ Drawing::RecordingCanvas::DrawFunc RSMaskShadowDrawable::CreateDrawFunc() const { auto ptr = std::static_pointer_cast(shared_from_this()); return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + Drawing::AutoCanvasRestore rst(*canvas, true); RSPropertyDrawableUtils::CeilMatrixTrans(canvas); ptr->drawCmdList_->Playback(*canvas); }; diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_foreground.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_foreground.cpp index 26cbf92533..873e13c45b 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_foreground.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_foreground.cpp @@ -29,6 +29,8 @@ constexpr int PARAM_TWO = 2; constexpr int MAX_LIGHT_SOURCES = 12; } // namespace +const bool BLUR_ENABLED = RSSystemProperties::GetBlurEnabled(); + // ==================================== // Binarization RSDrawable::Ptr RSBinarizationDrawable::OnGenerate(const RSRenderNode& node) @@ -200,15 +202,15 @@ bool RSForegroundColorDrawable::OnUpdate(const RSRenderNode& node) return true; } -RSDrawable::Ptr RSForegroundFilterDrawable::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSCompositingFilterDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return std::move(ret); } return nullptr; } -bool RSForegroundFilterDrawable::OnUpdate(const RSRenderNode& node) +bool RSCompositingFilterDrawable::OnUpdate(const RSRenderNode& node) { nodeId_ = node.GetId(); auto& rsFilter = node.GetRenderProperties().GetFilter(); @@ -225,6 +227,100 @@ bool RSForegroundFilterDrawable::OnUpdate(const RSRenderNode& node) return true; } +// foregroundFilter +RSDrawable::Ptr RSForegroundFilterDrawable::OnGenerate(const RSRenderNode& node) +{ + if (!BLUR_ENABLED) { + ROSEN_LOGD("RSForegroundFilterDrawable::OnGenerate close blur."); + return nullptr; + } + auto& rsFilter = node.GetRenderProperties().GetForegroundFilter(); + if (rsFilter == nullptr) { + return nullptr; + } + + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + return std::move(ret); + } + return nullptr; +} + +bool RSForegroundFilterDrawable::OnUpdate(const RSRenderNode& node) +{ + auto& rsFilter = node.GetRenderProperties().GetForegroundFilter(); + if (rsFilter == nullptr) { + return false; + } + needSync_ = true; + stagingBoundsRect_ = node.GetRenderProperties().GetBoundsRect(); + return true; +} + +Drawing::RecordingCanvas::DrawFunc RSForegroundFilterDrawable::CreateDrawFunc() const +{ + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + auto paintFilterCanvas = static_cast(canvas); + RSPropertyDrawableUtils::BeginForegroundFilter(*paintFilterCanvas, ptr->boundsRect_); + }; +} + +void RSForegroundFilterDrawable::OnSync() +{ + if (needSync_ == false) { + return; + } + boundsRect_ = stagingBoundsRect_; + needSync_ = false; +} + +// Restore RSForegroundFilter +RSDrawable::Ptr RSForegroundFilterRestoreDrawable::OnGenerate(const RSRenderNode& node) +{ + if (!BLUR_ENABLED) { + ROSEN_LOGD("RSForegroundFilterRestoreDrawable::OnGenerate close blur."); + return nullptr; + } + auto& rsFilter = node.GetRenderProperties().GetForegroundFilter(); + if (rsFilter == nullptr) { + return nullptr; + } + + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + return std::move(ret); + } + return nullptr; +} + +bool RSForegroundFilterRestoreDrawable::OnUpdate(const RSRenderNode& node) +{ + auto& rsFilter = node.GetRenderProperties().GetForegroundFilter(); + if (rsFilter == nullptr) { + return false; + } + needSync_ = true; + stagingForegroundFilter_ = rsFilter; + return true; +} + +Drawing::RecordingCanvas::DrawFunc RSForegroundFilterRestoreDrawable::CreateDrawFunc() const +{ + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + auto paintFilterCanvas = static_cast(canvas); + RSPropertyDrawableUtils::DrawForegroundFilter(*paintFilterCanvas, ptr->foregroundFilter_); + }; +} + +void RSForegroundFilterRestoreDrawable::OnSync() +{ + if (needSync_ == false) { + return; + } + foregroundFilter_ = std::move(stagingForegroundFilter_); + needSync_ = false; +} + RSDrawable::Ptr RSPixelStretchDrawable::OnGenerate(const RSRenderNode& node) { if (auto ret = std::make_shared(); ret->OnUpdate(node)) { diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp index 65acae5e8a..8d2d1cafd9 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp @@ -17,8 +17,8 @@ #include "common/rs_optional_trace.h" #include "platform/common/rs_log.h" -#include "render/rs_material_filter.h" #include "property/rs_properties_painter.h" +#include "render/rs_material_filter.h" namespace OHOS { namespace Rosen { @@ -182,7 +182,6 @@ void RSPropertyDrawableUtils::CeilMatrixTrans(Drawing::Canvas* canvas) { // The translation of the matrix is rounded to improve the hit ratio of skia blurfilter cache, // the function in for more details. - Drawing::AutoCanvasRestore rst(*canvas, true); auto matrix = canvas->GetTotalMatrix(); matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X))); matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y))); @@ -256,6 +255,54 @@ void RSPropertyDrawableUtils::DrawFilter(Drawing::Canvas* canvas, filter->PostProcess(*canvas); } +void RSPropertyDrawableUtils::BeginForegroundFilter(RSPaintFilterCanvas& canvas, const RectF& bounds) +{ + RS_OPTIONAL_TRACE_NAME("RSPropertyDrawableUtils::BeginForegroundFilter"); + auto surface = canvas.GetSurface(); + if (!surface) { + return; + } + std::shared_ptr offscreenSurface = surface->MakeSurface(bounds.width_, bounds.height_); + if (!offscreenSurface) { + return; + } + auto offscreenCanvas = std::make_shared(offscreenSurface.get()); + canvas.ReplaceMainScreenData(offscreenSurface, offscreenCanvas); + offscreenCanvas->Clear(Drawing::Color::COLOR_TRANSPARENT); + canvas.SavePCanvasList(); + canvas.RemoveAll(); + canvas.AddCanvas(offscreenCanvas.get()); +} + +void RSPropertyDrawableUtils::DrawForegroundFilter(RSPaintFilterCanvas& canvas, + const std::shared_ptr& rsFilter) +{ + RS_OPTIONAL_TRACE_NAME("DrawForegroundFilter restore"); + auto surface = canvas.GetSurface(); + std::shared_ptr imageSnapshot = nullptr; + if (surface) { + imageSnapshot = surface->GetImageSnapshot(); + } else { + ROSEN_LOGD("RSPropertyDrawableUtils::DrawForegroundFilter Surface null"); + } + + canvas.RestorePCanvasList(); + canvas.SwapBackMainScreenData(); + + if (rsFilter == nullptr) { + return; + } + + if (imageSnapshot == nullptr) { + ROSEN_LOGD("RSPropertyDrawableUtils::DrawForegroundFilter image null"); + return; + } + auto foregroundFilter = std::static_pointer_cast(rsFilter); + + foregroundFilter->DrawImageRect(canvas, imageSnapshot, Drawing::Rect(0, 0, imageSnapshot->GetWidth(), + imageSnapshot->GetHeight()), Drawing::Rect(0, 0, imageSnapshot->GetWidth(), imageSnapshot->GetHeight())); +} + int RSPropertyDrawableUtils::GetAndResetBlurCnt() { auto blurCnt = g_blurCnt; @@ -655,8 +702,8 @@ Drawing::Path RSPropertyDrawableUtils::CreateShadowPath(const std::shared_ptrClipPath(path, Drawing::ClipOp::DIFFERENCE, true); } @@ -706,6 +753,12 @@ void RSPropertyDrawableUtils::DrawUseEffect(RSPaintFilterCanvas* canvas) void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int blendMode, int blendModeApplyType) { + if (!canvas.HasOffscreenLayer() && RSPropertiesPainter::IsDangerousBlendMode(blendMode - 1, blendModeApplyType)) { + Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); + canvas.SaveLayer(maskLayerRec); + ROSEN_LOGD("Dangerous offscreen blendmode may produce transparent pixels, add extra offscreen here."); + } + // fast blend mode if (blendModeApplyType == static_cast(RSColorBlendApplyType::FAST)) { canvas.SetBlendMode({ blendMode - 1 }); // map blendMode to SkBlendMode @@ -713,10 +766,8 @@ void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int bl } // save layer mode - auto matrix = canvas.GetTotalMatrix(); - matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X))); - matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y))); - canvas.SetMatrix(matrix); + CeilMatrixTrans(&canvas); + Drawing::Brush blendBrush_; blendBrush_.SetAlphaF(canvas.GetAlpha()); blendBrush_.SetBlendMode(static_cast(blendMode - 1)); // map blendMode to Drawing::BlendMode @@ -727,11 +778,12 @@ void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int bl canvas.SetAlpha(1.0f); } -void RSPropertyDrawableUtils::EndBlendMode(RSPaintFilterCanvas& canvas) +void RSPropertyDrawableUtils::EndBlendMode(RSPaintFilterCanvas& canvas, int blendModeApplyType) { - canvas.RestoreEnv(); - canvas.RestoreAlpha(); - canvas.Restore(); + // RSRenderNodeDrawable will do other necessary work (restore canvas & env), we only need to restore alpha + if (blendModeApplyType != static_cast(RSColorBlendApplyType::FAST)) { + canvas.RestoreAlpha(); + } } Color RSPropertyDrawableUtils::CalculateInvertColor(const Color& backgroundColor) diff --git a/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp b/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp index 95f8dd81ed..245e6afe90 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp @@ -129,13 +129,12 @@ void RSRenderNodeDrawableAdapter::DrawRangeImpl( const auto& drawCmdList_ = renderNode_->drawCmdList_; - if (UNLIKELY(skipShadow_)) { - auto shadowIndex = renderNode_->drawCmdIndex_.shadowIndex_; - if (shadowIndex != -1 || start <= shadowIndex || end > shadowIndex) { - for (auto i = start; i < shadowIndex; i++) { + if (UNLIKELY(skipIndex_ != -1)) { + if (start <= skipIndex_ || end > skipIndex_) { + for (auto i = start; i < skipIndex_; i++) { drawCmdList_[i](&canvas, &rect); } - for (auto i = shadowIndex + 1; i < end; i++) { + for (auto i = skipIndex_ + 1; i < end; i++) { drawCmdList_[i](&canvas, &rect); } } @@ -326,4 +325,19 @@ bool RSRenderNodeDrawableAdapter::HasFilterOrEffect() const return renderNode_->drawCmdIndex_.shadowIndex_ != -1 || renderNode_->drawCmdIndex_.backgroundFilterIndex_ != -1 || renderNode_->drawCmdIndex_.useEffectIndex_ != -1; } +void RSRenderNodeDrawableAdapter::SetSkip(SkipType type) +{ + switch (type) { + case SkipType::SKIP_BACKGROUND_COLOR: + skipIndex_ = renderNode_->drawCmdIndex_.backgroundColorIndex_; + break; + case SkipType::SKIP_SHADOW: + skipIndex_ = renderNode_->drawCmdIndex_.shadowIndex_; + break; + case SkipType::NONE: + default: + skipIndex_ = -1; + break; + } +} } // namespace OHOS::Rosen::DrawableV2 diff --git a/rosen/modules/render_service_base/src/modifier/rs_render_modifier.cpp b/rosen/modules/render_service_base/src/modifier/rs_render_modifier.cpp index 3fee823b04..5a4ad425f2 100644 --- a/rosen/modules/render_service_base/src/modifier/rs_render_modifier.cpp +++ b/rosen/modules/render_service_base/src/modifier/rs_render_modifier.cpp @@ -21,7 +21,6 @@ #include "pixel_map.h" -#include "animation/rs_render_particle.h" #include "common/rs_obj_abs_geometry.h" #include "common/rs_vector2.h" #include "common/rs_vector4.h" diff --git a/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp b/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp index 31e59f74b9..fe54c0cfbe 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp @@ -902,17 +902,18 @@ CoreCanvas& RSPaintFilterCanvasBase::DetachPaint() } RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha) - : RSPaintFilterCanvasBase(canvas), alphaStack_({ std::clamp(alpha, 0.f, 1.f) }), // construct stack with given alpha - // Temporary fix, this default color should be 0x000000FF, fix this after foreground color refactor - envStack_({ Env({ RSColor(0xFF000000) }) }) // construct stack with default foreground color -{} + : RSPaintFilterCanvasBase(canvas), alphaStack_({ 1.0f }), + envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) +{ + (void)alpha; // alpha is no longer used, but we keep it for backward compatibility +} RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Surface* surface, float alpha) - : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), - alphaStack_({ std::clamp(alpha, 0.f, 1.f) }), // construct stack with given alpha - // Temporary fix, this default color should be 0x000000FF, fix this after foreground color refactor - envStack_({ Env({ RSColor(0xFF000000) }) }) // construct stack with default foreground color -{} + : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), alphaStack_({ 1.0f }), + envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) +{ + (void)alpha; // alpha is no longer used, but we keep it for backward compatibility +} Drawing::Surface* RSPaintFilterCanvas::GetSurface() const { @@ -1365,5 +1366,14 @@ bool RSPaintFilterCanvas::GetRecordDrawable() const { return recordDrawable_; } +bool RSPaintFilterCanvas::HasOffscreenLayer() const +{ + return envStack_.top().hasOffscreenLayer_; +} +void RSPaintFilterCanvas::SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) +{ + envStack_.top().hasOffscreenLayer_ = true; + RSPaintFilterCanvasBase::SaveLayer(saveLayerOps); +} } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp b/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp index f804f036fb..4534930318 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp @@ -1654,7 +1654,7 @@ void RSRenderNode::MarkFilterStatusChanged(bool isForeground, bool isFilterRegio std::shared_ptr RSRenderNode::GetFilterDrawable(bool isForeground) const { - auto slot = isForeground ? RSDrawableSlot::FOREGROUND_FILTER : RSDrawableSlot::BACKGROUND_FILTER; + auto slot = isForeground ? RSDrawableSlot::COMPOSITING_FILTER : RSDrawableSlot::BACKGROUND_FILTER; if (auto& drawable = drawableVec_[static_cast(slot)]) { if (auto filterDrawable = std::static_pointer_cast(drawable)) { return filterDrawable; @@ -1768,7 +1768,7 @@ void RSRenderNode::MarkFilterCacheFlagsAfterPrepare( filterDrawable->MarkFilterRegionIsLargeArea(); } filterDrawable->CheckClearFilterCache(); - auto slot = isForeground ? RSDrawableSlot::FOREGROUND_FILTER : RSDrawableSlot::BACKGROUND_FILTER; + auto slot = isForeground ? RSDrawableSlot::COMPOSITING_FILTER : RSDrawableSlot::BACKGROUND_FILTER; UpdateDirtySlotsAndPendingNodes(slot); } @@ -1790,7 +1790,7 @@ void RSRenderNode::MarkForceClearFilterCacheWhenWithInvisible() } filterDrawable->MarkFilterForceClearCache(); filterDrawable->CheckClearFilterCache(); - UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::FOREGROUND_FILTER); + UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::COMPOSITING_FILTER); } } @@ -2107,61 +2107,62 @@ void RSRenderNode::UpdateDisplayList() return; } + int8_t index = 0; // Note: the loop range is [begin, end], both end is included. - auto AppendDrawFunc = [&](RSDrawableSlot begin, RSDrawableSlot end) -> int8_t { - auto beginIndex = static_cast(begin); + auto AppendDrawFunc = [&](RSDrawableSlot end) -> int8_t { auto endIndex = static_cast(end); - for (int8_t i = beginIndex; i <= endIndex; ++i) { - if (const auto& drawable = drawableVec_[i]) { + for (; index <= endIndex; ++index) { + if (const auto& drawable = drawableVec_[index]) { stagingDrawCmdList_.emplace_back(drawable->CreateDrawFunc()); } } - // If the last drawable exist, return its index, otherwise return -1 + // If the end drawable exist, return its index, otherwise return -1 return drawableVec_[endIndex] != nullptr ? stagingDrawCmdList_.size() - 1 : -1; }; // Update index of SHADOW - stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SAVE_ALL, RSDrawableSlot::SHADOW); + stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SHADOW); - AppendDrawFunc(RSDrawableSlot::OUTLINE, RSDrawableSlot::OUTLINE); + AppendDrawFunc(RSDrawableSlot::OUTLINE); stagingDrawCmdIndex_.renderGroupBeginIndex_ = stagingDrawCmdList_.size(); // Update index of BACKGROUND_COLOR stagingDrawCmdIndex_.backgroundColorIndex_ = - AppendDrawFunc(RSDrawableSlot::BG_SAVE_BOUNDS, RSDrawableSlot::BACKGROUND_COLOR); + AppendDrawFunc(RSDrawableSlot::BACKGROUND_COLOR); // Update index of BACKGROUND_FILTER stagingDrawCmdIndex_.backgroundFilterIndex_ = - AppendDrawFunc(RSDrawableSlot::BACKGROUND_SHADER, RSDrawableSlot::BACKGROUND_FILTER); + AppendDrawFunc(RSDrawableSlot::BACKGROUND_FILTER); // Update index of USE_EFFECT - stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT, RSDrawableSlot::USE_EFFECT); + stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT); - AppendDrawFunc(RSDrawableSlot::BACKGROUND_STYLE, RSDrawableSlot::BG_RESTORE_BOUNDS); + AppendDrawFunc(RSDrawableSlot::BG_RESTORE_BOUNDS); if (drawableVecStatus_ & FRAME_PROPERTY) { // Update index of CONTENT_STYLE - stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::SAVE_FRAME, RSDrawableSlot::CONTENT_STYLE); + stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::CONTENT_STYLE); // Update index of BACKGROUND_END stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdIndex_.contentIndex_ == -1 ? stagingDrawCmdList_.size() : stagingDrawCmdIndex_.contentIndex_; // Update index of CHILDREN - stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN, RSDrawableSlot::CHILDREN); + stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN); stagingDrawCmdIndex_.foregroundBeginIndex_ = stagingDrawCmdList_.size(); - AppendDrawFunc(RSDrawableSlot::FOREGROUND_STYLE, RSDrawableSlot::RESTORE_FRAME); + AppendDrawFunc(RSDrawableSlot::RESTORE_FRAME); } else { // Nothing inside frame, skip useless slots and update indexes stagingDrawCmdIndex_.contentIndex_ = -1; stagingDrawCmdIndex_.childrenIndex_ = -1; stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdList_.size(); stagingDrawCmdIndex_.foregroundBeginIndex_ = stagingDrawCmdList_.size(); + index = static_cast(RSDrawableSlot::FG_SAVE_BOUNDS); } stagingDrawCmdIndex_.renderGroupEndIndex_ = stagingDrawCmdList_.size(); - AppendDrawFunc(RSDrawableSlot::FG_SAVE_BOUNDS, RSDrawableSlot::RESTORE_ALL); + AppendDrawFunc(RSDrawableSlot::RESTORE_ALL); stagingDrawCmdIndex_.endIndex_ = stagingDrawCmdList_.size(); stagingRenderParams_->SetContentEmpty(false); #endif diff --git a/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp b/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp index bec2247b14..c20be0b634 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp @@ -172,9 +172,8 @@ void RSSurfaceRenderNode::UpdateHwcDisabledBySrcRect(bool hasRotation) if (IsYUVBufferFormat()) { auto width = static_cast(buffer->GetSurfaceBufferWidth()); auto height = static_cast(buffer->GetSurfaceBufferHeight()); - isHardwareForcedDisabledBySrcRect_ = hasRotation ? - srcRect_.width_ + 1 < width : - srcRect_.height_ + 1 < height; + isHardwareForcedDisabledBySrcRect_ = !GetAncoForceDoDirect() && + (hasRotation ? srcRect_.width_ + 1 < width : srcRect_.height_ + 1 < height); RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%llu disableBySrc:%d src:[%d, %d]" \ " buffer:[%d, %d] hasRotation:%d", GetName().c_str(), GetId(), isHardwareForcedDisabledBySrcRect_, srcRect_.width_, srcRect_.height_, width, height, hasRotation); diff --git a/rosen/modules/render_service_base/src/platform/darwin/rs_marshalling_helper.cpp b/rosen/modules/render_service_base/src/platform/darwin/rs_marshalling_helper.cpp index b841a007ad..a5cbfb1521 100644 --- a/rosen/modules/render_service_base/src/platform/darwin/rs_marshalling_helper.cpp +++ b/rosen/modules/render_service_base/src/platform/darwin/rs_marshalling_helper.cpp @@ -25,6 +25,7 @@ #include "animation/rs_render_interpolating_spring_animation.h" #include "animation/rs_render_keyframe_animation.h" #include "animation/rs_render_particle.h" +#include "animation/rs_particle_noise_field.h" #include "animation/rs_render_path_animation.h" #include "animation/rs_render_spring_animation.h" #include "animation/rs_render_transition.h" @@ -172,6 +173,16 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + return {}; +} +bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + return {}; +} + // MotionBlurPara bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr& val) { @@ -415,6 +426,7 @@ MARSHALLING_AND_UNMARSHALLING(RSRenderAnimatableProperty) EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ + EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr>) \ EXPLICIT_INSTANTIATION(TEMPLATE, RSRenderParticleVector) \ EXPLICIT_INSTANTIATION(TEMPLATE, Vector2f) \ diff --git a/rosen/modules/render_service_base/src/platform/darwin/rs_render_service_client.cpp b/rosen/modules/render_service_base/src/platform/darwin/rs_render_service_client.cpp index d35ee40805..6912845315 100644 --- a/rosen/modules/render_service_base/src/platform/darwin/rs_render_service_client.cpp +++ b/rosen/modules/render_service_base/src/platform/darwin/rs_render_service_client.cpp @@ -110,6 +110,12 @@ std::shared_ptr RSRenderServiceClient::CreateVSyncReceiver( return std::make_shared(); } +std::shared_ptr RSRenderServiceClient::CreatePixelMapFromSurfaceId(uint64_t surfaceId, + const Rect &srcRect) +{ + return nullptr; +} + bool RSRenderServiceClient::TakeSurfaceCapture(NodeId id, std::shared_ptr callback, float scaleX, float scaleY, SurfaceCaptureType surfaceCaptureType, bool isSync) { diff --git a/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp b/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp index b10462f5b4..cc8584a563 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp +++ b/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp @@ -20,15 +20,9 @@ namespace OHOS { namespace Rosen { -RSListenedCanvas::RSListenedCanvas(Drawing::Canvas& canvas, float alpha) - : RSPaintFilterCanvas(&canvas, alpha) -{ -} +RSListenedCanvas::RSListenedCanvas(Drawing::Canvas& canvas) : RSPaintFilterCanvas(&canvas) {} -RSListenedCanvas::RSListenedCanvas(Drawing::Surface& surface, float alpha) - : RSPaintFilterCanvas(&surface, alpha) -{ -} +RSListenedCanvas::RSListenedCanvas(Drawing::Surface& surface) : RSPaintFilterCanvas(&surface) {} void RSListenedCanvas::SetListener(const std::shared_ptr &listener) { diff --git a/rosen/modules/render_service_base/src/platform/ohos/rs_marshalling_helper.cpp b/rosen/modules/render_service_base/src/platform/ohos/rs_marshalling_helper.cpp index 3eee0d70d6..f7ccef3b4e 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/rs_marshalling_helper.cpp +++ b/rosen/modules/render_service_base/src/platform/ohos/rs_marshalling_helper.cpp @@ -29,6 +29,7 @@ #include "animation/rs_render_interpolating_spring_animation.h" #include "animation/rs_render_keyframe_animation.h" #include "animation/rs_render_particle.h" +#include "animation/rs_particle_noise_field.h" #include "animation/rs_render_particle_animation.h" #include "animation/rs_render_path_animation.h" #include "animation/rs_render_spring_animation.h" @@ -619,6 +620,47 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + bool success = Marshalling(parcel, val->fieldStrength_); + success = success && Marshalling(parcel, val->fieldShape_); + success = success && Marshalling(parcel, val->fieldSize_.x_) && Marshalling(parcel, val->fieldSize_.y_); + success = success && Marshalling(parcel, val->fieldCenter_.x_) && Marshalling(parcel, val->fieldCenter_.y_); + success = success && Marshalling(parcel, val->fieldFeather_) && Marshalling(parcel, val->noiseScale_); + success = success && Marshalling(parcel, val->noiseFrequency_) && Marshalling(parcel, val->noiseAmplitude_); + return success; +} + +bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + int fieldStrength = 0; + ShapeType fieldShape = ShapeType::RECT; + float fieldSizeX = 0.f; + float fieldSizeY = 0.f; + float fieldCenterX = 0.f; + float fieldCenterY = 0.f; + uint16_t fieldFeather = 0; + float noiseScale = 0.f; + float noiseFrequency = 0.f; + float noiseAmplitude = 0.f; + + bool success = Unmarshalling(parcel, fieldStrength); + success = success && Unmarshalling(parcel, fieldShape); + success = success && Unmarshalling(parcel, fieldSizeX) && Unmarshalling(parcel, fieldSizeY); + Vector2f fieldSize(fieldSizeX, fieldSizeY); + success = success && Unmarshalling(parcel, fieldCenterX) && Unmarshalling(parcel, fieldCenterY); + Vector2f fieldCenter(fieldCenterX, fieldCenterY); + success = success && Unmarshalling(parcel, fieldFeather); + success = success && Unmarshalling(parcel, noiseScale); + success = success && Unmarshalling(parcel, noiseFrequency); + success = success && Unmarshalling(parcel, noiseAmplitude); + if (success) { + val = std::make_shared(fieldStrength, fieldShape, fieldSize, fieldCenter, fieldFeather, + noiseScale, noiseFrequency, noiseAmplitude); + } + return success; +} + // MotionBlurPara bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr& val) { @@ -791,7 +833,7 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, RenderParticleParaType>> valChangeOverLife; bool success = Unmarshalling(parcel, colorValStart) && Unmarshalling(parcel, colorValEnd) && - Unmarshalling(parcel, updator); + Unmarshalling(parcel, distribution) && Unmarshalling(parcel, updator); if (updator == ParticleUpdator::RANDOM) { success = success && Unmarshalling(parcel, redRandomStart) && Unmarshalling(parcel, redRandomEnd) && Unmarshalling(parcel, greenRandomStart) && Unmarshalling(parcel, greenRandomEnd) && @@ -858,8 +901,8 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, RenderParticleColorParaT Range greenRandom(greenRandomStart, greenRandomEnd); Range blueRandom(blueRandomStart, blueRandomEnd); Range alphaRandom(alphaRandomStart, alphaRandomEnd); - val = RenderParticleColorParaType( - colorVal, updator, redRandom, greenRandom, blueRandom, alphaRandom, std::move(valChangeOverLife)); + val = RenderParticleColorParaType(colorVal, distribution, updator, redRandom, greenRandom, blueRandom, + alphaRandom, std::move(valChangeOverLife)); } return success; } @@ -1705,6 +1748,7 @@ MARSHALLING_AND_UNMARSHALLING(RSRenderAnimatableProperty) EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ + EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::vector>) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, RSRenderParticleVector) \ diff --git a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_client.cpp b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_client.cpp index a524301da6..2cdcc92162 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_client.cpp +++ b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_client.cpp @@ -14,6 +14,8 @@ */ #include "transaction/rs_render_service_client.h" +#include "surface_type.h" +#include "surface_utils.h" #include "backend/rs_surface_ohos_gl.h" #include "backend/rs_surface_ohos_raster.h" @@ -171,6 +173,21 @@ std::shared_ptr RSRenderServiceClient::CreateVSyncReceiver( return std::make_shared(conn, token->AsObject(), looper, name); } +std::shared_ptr RSRenderServiceClient::CreatePixelMapFromSurfaceId(uint64_t surfaceId, + const Rect &srcRect) +{ + auto renderService = RSRenderServiceConnectHub::GetRenderService(); + if (renderService == nullptr) { + return nullptr; + } + sptr surface = SurfaceUtils::GetInstance()->GetSurface(surfaceId); + if (surface == nullptr) { + return nullptr; + } + + return renderService->CreatePixelMapFromSurface(surface, srcRect); +} + void RSRenderServiceClient::TriggerSurfaceCaptureCallback(NodeId id, Media::PixelMap* pixelmap) { ROSEN_LOGD("RSRenderServiceClient::Into TriggerSurfaceCaptureCallback nodeId:[%{public}" PRIu64 "]", id); @@ -444,7 +461,7 @@ bool RSRenderServiceClient::GetShowRefreshRateEnabled() return renderService->GetShowRefreshRateEnabled(); } - + void RSRenderServiceClient::SetShowRefreshRateEnabled(bool enable) { auto renderService = RSRenderServiceConnectHub::GetRenderService(); diff --git a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.cpp b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.cpp index eb585dfa0a..b66dd3bf7c 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.cpp +++ b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.cpp @@ -238,6 +238,44 @@ sptr RSRenderServiceConnectionProxy::CreateVSyncConnection(con return conn; } +std::shared_ptr RSRenderServiceConnectionProxy::CreatePixelMapFromSurface(sptr surface, + const Rect &srcRect) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (surface == nullptr) { + return nullptr; + } + + auto producer = surface->GetProducer(); + if (producer == nullptr) { + return nullptr; + } + + if (!data.WriteInterfaceToken(RSIRenderServiceConnection::GetDescriptor())) { + return nullptr; + } + data.WriteRemoteObject(producer->AsObject()); + data.WriteInt32(srcRect.x); + data.WriteInt32(srcRect.y); + data.WriteInt32(srcRect.w); + data.WriteInt32(srcRect.h); + option.SetFlags(MessageOption::TF_SYNC); + uint32_t code = static_cast(RSIRenderServiceConnectionInterfaceCode::CREATE_PIXEL_MAP_FROM_SURFACE); + int32_t err = Remote()->SendRequest(code, data, reply, option); + if (err != NO_ERROR) { + ROSEN_LOGE("RSRenderServiceConnectionProxy::CreatePixelMapFromSurface: Send Request err."); + return nullptr; + } + + std::shared_ptr pixelMap = nullptr; + if (reply.ReadBool()) { + pixelMap.reset(Media::PixelMap::Unmarshalling(reply)); + } + return pixelMap; +} + int32_t RSRenderServiceConnectionProxy::SetFocusAppInfo( int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId) { diff --git a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.h b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.h index f80b3fa590..3cbf98bdd6 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.h +++ b/rosen/modules/render_service_base/src/platform/ohos/rs_render_service_connection_proxy.h @@ -47,6 +47,8 @@ public: uint64_t id = 0, NodeId windowNodeId = 0) override; + std::shared_ptr CreatePixelMapFromSurface(sptr surface, const Rect &srcRect) override; + int32_t SetFocusAppInfo( int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId) override; diff --git a/rosen/modules/render_service_base/src/platform/windows/rs_marshalling_helper.cpp b/rosen/modules/render_service_base/src/platform/windows/rs_marshalling_helper.cpp index 547d2f506f..ef99e05251 100644 --- a/rosen/modules/render_service_base/src/platform/windows/rs_marshalling_helper.cpp +++ b/rosen/modules/render_service_base/src/platform/windows/rs_marshalling_helper.cpp @@ -25,6 +25,7 @@ #include "animation/rs_render_interpolating_spring_animation.h" #include "animation/rs_render_keyframe_animation.h" #include "animation/rs_render_particle.h" +#include "animation/rs_particle_noise_field.h" #include "animation/rs_render_path_animation.h" #include "animation/rs_render_spring_animation.h" #include "animation/rs_render_transition.h" @@ -174,6 +175,16 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + return {}; +} + +bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr& val) +{ + return {}; +} + // MotionBlurPara bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr& val) { @@ -426,6 +437,7 @@ MARSHALLING_AND_UNMARSHALLING(RSRenderAnimatableProperty) EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ + EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr) \ EXPLICIT_INSTANTIATION(TEMPLATE, RSRenderParticleVector) \ EXPLICIT_INSTANTIATION(TEMPLATE, Vector2f) \ EXPLICIT_INSTANTIATION(TEMPLATE, Vector4) \ diff --git a/rosen/modules/render_service_base/src/platform/windows/rs_render_service_client.cpp b/rosen/modules/render_service_base/src/platform/windows/rs_render_service_client.cpp index 736f164d37..c2299e5cde 100644 --- a/rosen/modules/render_service_base/src/platform/windows/rs_render_service_client.cpp +++ b/rosen/modules/render_service_base/src/platform/windows/rs_render_service_client.cpp @@ -110,6 +110,12 @@ std::shared_ptr RSRenderServiceClient::CreateVSyncReceiver( return std::make_shared(); } +std::shared_ptr RSRenderServiceClient::CreatePixelMapFromSurfaceId(uint64_t surfaceId, + const Rect &srcRect) +{ + return nullptr; +} + bool RSRenderServiceClient::TakeSurfaceCapture(NodeId id, std::shared_ptr callback, float scaleX, float scaleY, SurfaceCaptureType surfaceCaptureType, bool isSync) { diff --git a/rosen/modules/render_service_base/src/property/rs_properties.cpp b/rosen/modules/render_service_base/src/property/rs_properties.cpp index 83d7f3726d..a774d75ab9 100644 --- a/rosen/modules/render_service_base/src/property/rs_properties.cpp +++ b/rosen/modules/render_service_base/src/property/rs_properties.cpp @@ -53,7 +53,7 @@ constexpr uint8_t BORDER_TYPE_NONE = (uint32_t)BorderStyle::NONE; using ResetPropertyFunc = void (*)(RSProperties* prop); // Every modifier before RSModifierType::CUSTOM is property modifier, and it should have a ResetPropertyFunc // NOTE: alway add new resetter when adding new property modifier -const std::array(RSModifierType::CUSTOM)> g_propertyResetterLUT = { +constexpr static std::array(RSModifierType::CUSTOM)> g_propertyResetterLUT = { nullptr, // INVALID nullptr, // BOUNDS nullptr, // FRAME @@ -141,6 +141,7 @@ const std::array(RSModifierType::CUSTOM)> g_ [](RSProperties* prop) { prop->SetIlluminatedType(-1); }, // ILLUMINATED_TYPE [](RSProperties* prop) { prop->SetBloom({}); }, // BLOOM [](RSProperties* prop) { prop->SetEmitterUpdater({}); }, // PARTICLE_EMITTER_UPDATER + [](RSProperties* prop) { prop->SetParticleNoiseField({}); }, // PARTICLE_NOISE_FIELD [](RSProperties* prop) { prop->SetForegroundEffectRadius(0.f); }, // FOREGROUND_EFFECT_RADIUS [](RSProperties* prop) { prop->SetMotionBlurPara({}); }, // MOTION_BLUR_PARA [](RSProperties* prop) { prop->SetDynamicDimDegree({}); }, // DYNAMIC_LIGHT_UP_DEGREE @@ -159,6 +160,10 @@ const std::array(RSModifierType::CUSTOM)> g_ [](RSProperties* prop) { prop->SetForegroundBlurRadiusX(0.f); }, // FOREGROUND_BLUR_RADIUS_X [](RSProperties* prop) { prop->SetForegroundBlurRadiusY(0.f); }, // FOREGROUND_BLUR_RADIUS_Y }; + +// Check if g_propertyResetterLUT size match and is fully initialized (the last element should never be nullptr) +static_assert(g_propertyResetterLUT.size() == static_cast(RSModifierType::CUSTOM)); +static_assert(g_propertyResetterLUT.back() != nullptr); } // namespace // Only enable filter cache when uni-render is enabled and filter cache is enabled @@ -1170,6 +1175,17 @@ void RSProperties::SetEmitterUpdater(const std::shared_ptr& para contentDirty_ = true; } +void RSProperties::SetParticleNoiseField(const std::shared_ptr& para) +{ + particleNoiseField_ = para; + if (particleNoiseField_) { + isDrawn_ = true; + } + filterNeedUpdate_ = true; + SetDirty(); + contentDirty_ = true; +} + void RSProperties::SetDynamicLightUpRate(const std::optional& rate) { dynamicLightUpRate_ = rate; @@ -1249,6 +1265,11 @@ const std::shared_ptr& RSProperties::GetEmitterUpdater() const return emitterUpdater_; } +const std::shared_ptr& RSProperties::GetParticleNoiseField() const +{ + return particleNoiseField_; +} + void RSProperties::IfLinearGradientBlurInvalid() { if (linearGradientBlurPara_ != nullptr) { diff --git a/rosen/modules/render_service_base/src/property/rs_property_drawable.cpp b/rosen/modules/render_service_base/src/property/rs_property_drawable.cpp index 055e63a764..ce393a6515 100644 --- a/rosen/modules/render_service_base/src/property/rs_property_drawable.cpp +++ b/rosen/modules/render_service_base/src/property/rs_property_drawable.cpp @@ -168,6 +168,7 @@ static const std::unordered_map g_proper { RSModifierType::ENV_FOREGROUND_COLOR, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR }, { RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY }, { RSModifierType::PARTICLE_EMITTER_UPDATER, RSPropertyDrawableSlot::PARTICLE_EFFECT }, + { RSModifierType::PARTICLE_NOISE_FIELD, RSPropertyDrawableSlot::PARTICLE_EFFECT }, { RSModifierType::DYNAMIC_DIM_DEGREE, RSPropertyDrawableSlot::DYNAMIC_DIM }, { RSModifierType::GEOMETRYTRANS, RSPropertyDrawableSlot::INVALID }, }; diff --git a/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp b/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp index f864891fa3..1be2984830 100644 --- a/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp +++ b/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp @@ -17,25 +17,16 @@ #include -#include "include/core/SkMaskFilter.h" -#include "include/core/SkPaint.h" -#include "include/core/SkPoint3.h" -#include "include/effects/SkImageFilters.h" -#include "include/effects/SkLumaColorFilter.h" -#include "include/utils/SkShadowUtils.h" -#include "src/image/SkImage_Base.h" - #include "common/rs_obj_abs_geometry.h" #include "common/rs_optional_trace.h" #include "pipeline/rs_canvas_render_node.h" #include "pipeline/rs_effect_render_node.h" #include "pipeline/rs_paint_filter_canvas.h" #include "platform/common/rs_log.h" +#include "platform/common/rs_system_properties.h" #include "property/rs_properties.h" #include "property/rs_properties_def.h" #include "property/rs_properties_painter.h" -#include "render/rs_skia_filter.h" -#include "platform/common/rs_system_properties.h" namespace { constexpr int PARAM_DOUBLE = 2; @@ -1096,9 +1087,9 @@ RSBlendSaveLayerDrawable::RSBlendSaveLayerDrawable(int blendMode) void RSBlendSaveLayerDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - if (canvas.GetBlendOffscreenLayerCnt() == 0 && - RSPropertiesPainter::IsDangerousBlendMode(static_cast(blendBrush_.GetBlendMode()), - static_cast(RSColorBlendApplyType::SAVE_LAYER))) { + if (!canvas.HasOffscreenLayer() && + RSPropertiesPainter::IsDangerousBlendMode( + static_cast(blendBrush_.GetBlendMode()), static_cast(RSColorBlendApplyType::SAVE_LAYER))) { Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); canvas.SaveLayer(maskLayerRec); ROSEN_LOGD("Dangerous offscreen blendmode may produce transparent pixels, add extra offscreen here."); @@ -1118,7 +1109,7 @@ void RSBlendSaveLayerDrawable::Draw(const RSRenderContent& content, RSPaintFilte void RSBlendFastDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - if (canvas.GetBlendOffscreenLayerCnt() == 0 && + if (!canvas.HasOffscreenLayer() && RSPropertiesPainter::IsDangerousBlendMode(blendMode_ - 1, static_cast(RSColorBlendApplyType::FAST))) { Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); canvas.SaveLayer(maskLayerRec); @@ -1127,16 +1118,14 @@ void RSBlendFastDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanv canvas.SetBlendMode({ blendMode_ - 1 }); // map blendMode to SkBlendMode } - void RSBlendSaveLayerRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - canvas.RestoreAlpha(); - canvas.Restore(); + // SAVE_ALL slot will do all necessary restore } void RSBlendFastRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - canvas.Restore(); + // SAVE_ALL slot will do all necessary restore } } // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/src/render/rs_border.cpp b/rosen/modules/render_service_base/src/render/rs_border.cpp index 4db088d670..beac97a919 100644 --- a/rosen/modules/render_service_base/src/render/rs_border.cpp +++ b/rosen/modules/render_service_base/src/render/rs_border.cpp @@ -32,9 +32,18 @@ constexpr float BOTTOM_END = 90.0f; constexpr float LEFT_START = 135.0f; constexpr float LEFT_END = 180.0f; constexpr float SWEEP_ANGLE = 45.0f; -constexpr float EXTEND = 1024.0f; } // namespace +// defines short names for widths/half widths of each borders +#define LEFTW GetWidth(RSBorder::LEFT) +#define LEFTW2 GetWidth(RSBorder::LEFT) / 2.f +#define RIGHTW GetWidth(RSBorder::RIGHT) +#define RIGHTW2 GetWidth(RSBorder::RIGHT) / 2.f +#define TOPW GetWidth(RSBorder::TOP) +#define TOPW2 GetWidth(RSBorder::TOP) / 2.f +#define BOTTOMW GetWidth(RSBorder::BOTTOM) +#define BOTTOMW2 GetWidth(RSBorder::BOTTOM) / 2.f + RSBorder::RSBorder(const bool& isOutline) { if (isOutline) { @@ -291,304 +300,419 @@ void RSBorder::PaintFourLine(Drawing::Canvas& canvas, Drawing::Pen& pen, RectF r void RSBorder::PaintTopPath(Drawing::Canvas& canvas, Drawing::Pen& pen, const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const { - float offsetX = rrect.GetRect().GetLeft(); - float offsetY = rrect.GetRect().GetTop(); - float width = rrect.GetRect().GetWidth(); - auto style = GetStyle(RSBorder::TOP); - float leftW = GetWidth(RSBorder::LEFT); - float topW = GetWidth(RSBorder::TOP); - float rightW = GetWidth(RSBorder::RIGHT); - float bottomW = GetWidth(RSBorder::BOTTOM); - float x = offsetX + leftW / 2.0f; - float y = offsetY + topW / 2.0f; - float w = std::max(0.0f, width - (leftW + rightW) / 2.0f); - float tlX = std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS).GetX() - (topW + leftW) / 4.0f); - float tlY = std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS).GetY() - (topW + leftW) / 4.0f); - float trX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS).GetX() - (topW + rightW) / 4.0f); - float trY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS).GetY() - (topW + rightW) / 4.0f); - if (topW > 0.f) { + if (TOPW > 0.f) { + float offsetX = rrect.GetRect().GetLeft(); + float offsetY = rrect.GetRect().GetTop(); + float width = rrect.GetRect().GetWidth(); + float x = offsetX + LEFTW2; + float y = offsetY + TOPW2; + Drawing::Point tlRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS); + Drawing::Point trRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS); ApplyLineStyle(pen, RSBorder::TOP, width); - auto rectStart = Drawing::Rect(x, y, x + tlX * 2.0f, y + tlY * 2.0f); - auto rectEnd = Drawing::Rect(x + w - trX * 2.0f, y, x + w, y + trY * 2.0f); - Drawing::Path topBorder; - pen.SetWidth(std::max(std::max(leftW, topW), std::max(rightW, bottomW))); + if (GetStyle(RSBorder::TOP) != BorderStyle::DOTTED) { + pen.SetWidth(std::max(std::max(LEFTW, TOPW), std::max(RIGHTW, BOTTOMW))); + } Drawing::AutoCanvasRestore acr(canvas, true); - canvas.ClipRect({ offsetX, offsetY, offsetX + width, innerRectCenter.GetY() }); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(tlX, 0.f) && !ROSEN_EQ(leftW, 0.f))) { - topBorder.MoveTo(offsetX, y); - topBorder.LineTo(x, y); - Drawing::Path topClipPath; - topClipPath.MoveTo(offsetX - leftW, offsetY - topW); - topClipPath.LineTo(offsetX + leftW * EXTEND, offsetY + topW * EXTEND); - topClipPath.LineTo(offsetX, offsetY + topW * EXTEND); - topClipPath.Close(); - topClipPath.Offset(-0.5, 0); - canvas.ClipPath(topClipPath, Drawing::ClipOp::DIFFERENCE, true); - } - topBorder.ArcTo(rectStart.GetLeft(), rectStart.GetTop(), rectStart.GetRight(), rectStart.GetBottom(), - TOP_START, SWEEP_ANGLE); - topBorder.ArcTo(rectEnd.GetLeft(), rectEnd.GetTop(), rectEnd.GetRight(), rectEnd.GetBottom(), - TOP_END, SWEEP_ANGLE + 0.5f); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(trX, 0.f) && !ROSEN_EQ(rightW, 0.f))) { - topBorder.LineTo(offsetX + width, y); - Drawing::Path topClipPath; - topClipPath.MoveTo(offsetX + width + rightW, offsetY - topW); - topClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY + topW * EXTEND); - topClipPath.LineTo(offsetX + width, offsetY + topW * EXTEND); - topClipPath.Close(); - topClipPath.Offset(0.5, 0); - canvas.ClipPath(topClipPath, Drawing::ClipOp::DIFFERENCE, true); - } + Drawing::Path topClipPath; + // top left intersection point with innerRect center + Drawing::Point tlip = GetTLIP(rrect, innerRectCenter); + // top right intersection point with innerRect center + Drawing::Point trip = GetTRIP(rrect, innerRectCenter); + // draw clipping path for top border + topClipPath.MoveTo(offsetX, offsetY); + topClipPath.LineTo(tlip.GetX(), tlip.GetY()); + topClipPath.LineTo(trip.GetX(), trip.GetY()); + topClipPath.LineTo(offsetX + width, offsetY); + topClipPath.Close(); + canvas.ClipPath(topClipPath, Drawing::ClipOp::INTERSECT, true); + // calc rectangles to draw left top and right top arcs according to radii values + float startArcWidth = std::min(width - LEFTW, tlRad.GetX() * 2.f); + float endArcWidth = std::min(width - RIGHTW, trRad.GetX() * 2.f); + float startArcHeight = std::min(rrect.GetRect().GetHeight() - TOPW, tlRad.GetY() * 2.f); + float endArcHeight = std::min(rrect.GetRect().GetHeight() - TOPW, trRad.GetY() * 2.f); + auto rs = Drawing::Rect(x, y, x + startArcWidth, y + startArcHeight); + auto re = Drawing::Rect(offsetX + width - RIGHTW / 2.f - endArcWidth, y, + offsetX + width - RIGHTW / 2.f, y + endArcHeight); + // create drawing path from left top corner to right top corner + Drawing::Path topBorder; + topBorder.MoveTo(std::min(x, offsetX + tlRad.GetX() / 2.f), y + tlRad.GetY() / 2.f); + topBorder.ArcTo(rs.GetLeft(), rs.GetTop(), rs.GetRight(), rs.GetBottom(), TOP_START, SWEEP_ANGLE); + topBorder.ArcTo(re.GetLeft(), re.GetTop(), re.GetRight(), re.GetBottom(), TOP_END, SWEEP_ANGLE); + topBorder.LineTo(std::max(offsetX + width - RIGHTW2, offsetX + width - trRad.GetX() / 2.f), + y + trRad.GetY() / 2.f); canvas.AttachPen(pen); - if (style == BorderStyle::SOLID) { - auto r = topBorder.GetBounds(); - canvas.DrawRect(r); - canvas.DetachPen(); + if (GetStyle(RSBorder::TOP) == BorderStyle::SOLID) { Drawing::Brush brush; brush.SetColor(pen.GetColor()); brush.SetAntiAlias(true); canvas.AttachBrush(brush); - r.MakeOutset(-pen.GetWidth() / PARAM_DOUBLE, -pen.GetWidth() / PARAM_DOUBLE); - canvas.DrawRect(r); + canvas.DrawRect(topBorder.GetBounds()); canvas.DetachBrush(); } else { canvas.DrawPath(topBorder); - canvas.DetachPen(); } + canvas.DetachPen(); } } void RSBorder::PaintRightPath(Drawing::Canvas& canvas, Drawing::Pen& pen, const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const { - float offsetX = rrect.GetRect().GetLeft(); - float offsetY = rrect.GetRect().GetTop(); - float width = rrect.GetRect().GetWidth(); - float height = rrect.GetRect().GetHeight(); - auto style = GetStyle(RSBorder::RIGHT); - float leftW = GetWidth(RSBorder::LEFT); - float topW = GetWidth(RSBorder::TOP); - float rightW = GetWidth(RSBorder::RIGHT); - float bottomW = GetWidth(RSBorder::BOTTOM); - float x = offsetX + leftW / 2.0f; - float y = offsetY + topW / 2.0f; - float w = std::max(0.0f, width - (leftW + rightW) / 2.0f); - float h = std::max(0.0f, height - (topW + bottomW) / 2.0f); - float trX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS).GetX() - (topW + rightW) / 4.0f); - float trY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS).GetY() - (topW + rightW) / 4.0f); - float brX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS).GetX() - (bottomW + rightW) / 4.0f); - float brY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS).GetY() - (bottomW + rightW) / 4.0f); - if (rightW > 0.f) { + if (RIGHTW > 0.f) { + float offsetX = rrect.GetRect().GetLeft(); + float offsetY = rrect.GetRect().GetTop(); + float height = rrect.GetRect().GetHeight(); + float width = rrect.GetRect().GetWidth(); + float x = offsetX + width - RIGHTW2; + float y = offsetY + TOPW2; + Drawing::Point trRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS); + Drawing::Point brRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS); ApplyLineStyle(pen, RSBorder::RIGHT, height); - auto rectStart = Drawing::Rect(x + w - trX * 2.0f, y, x + w, y + trY * 2.0f); - auto rectEnd = Drawing::Rect(x + w - brX * 2.0f, y + h - brY * 2.0f, x + w, y + h); - Drawing::Path rightBorder; - pen.SetWidth(std::max(std::max(leftW, topW), std::max(rightW, bottomW))); + if (GetStyle(RSBorder::RIGHT) != BorderStyle::DOTTED) { + pen.SetWidth(std::max(std::max(LEFTW, TOPW), std::max(RIGHTW, BOTTOMW))); + } Drawing::AutoCanvasRestore acr(canvas, true); - canvas.ClipRect({ innerRectCenter.GetX(), offsetY, offsetX + width, offsetY + height }); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(trX, 0.f) && !ROSEN_EQ(topW, 0.f))) { - rightBorder.MoveTo(offsetX + width - rightW / 2.0f, offsetY); - rightBorder.LineTo(x + w - trX * 2.0f, y); - Drawing::Path rightClipPath; - rightClipPath.MoveTo(offsetX + width + rightW, offsetY - topW); - rightClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY + topW * EXTEND); - rightClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY); - rightClipPath.Close(); - rightClipPath.Offset(0, -0.5); - canvas.ClipPath(rightClipPath, Drawing::ClipOp::DIFFERENCE, true); - } - rightBorder.ArcTo(rectStart.GetLeft(), rectStart.GetTop(), rectStart.GetRight(), rectStart.GetBottom(), - RIGHT_START, SWEEP_ANGLE); - rightBorder.ArcTo(rectEnd.GetLeft(), rectEnd.GetTop(), rectEnd.GetRight(), rectEnd.GetBottom(), - RIGHT_END, SWEEP_ANGLE + 0.5f); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(brX, 0.f) && !ROSEN_EQ(bottomW, 0.f))) { - rightBorder.LineTo(offsetX + width - rightW / 2.0f, offsetY + height); - Drawing::Path rightClipPath; - rightClipPath.MoveTo(offsetX + width + rightW, offsetY + height + bottomW); - rightClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY + height - bottomW * EXTEND); - rightClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY + height); - rightClipPath.Close(); - rightClipPath.Offset(0, 0.5); - canvas.ClipPath(rightClipPath, Drawing::ClipOp::DIFFERENCE, true); - } + Drawing::Path rightClipPath; + // top rigth intersection point with innerRect center + Drawing::Point trip = GetTRIP(rrect, innerRectCenter); + // bottom right intersection point with innerRect center + Drawing::Point brip = GetBRIP(rrect, innerRectCenter); + // draw clipping path for right border + rightClipPath.MoveTo(offsetX + width, offsetY); + rightClipPath.LineTo(trip.GetX(), trip.GetY()); + rightClipPath.LineTo(brip.GetX(), brip.GetY()); + rightClipPath.LineTo(offsetX + width, offsetY + height); + rightClipPath.Close(); + canvas.ClipPath(rightClipPath, Drawing::ClipOp::INTERSECT, true); + // calc rectangles to draw right top and right bottom arcs according to radii values + float startArcWidth = std::min(width - RIGHTW, trRad.GetX() * 2.f); + float endArcWidth = std::min(width - RIGHTW, brRad.GetX() * 2.f); + float startArcHeight = std::min(height - TOPW, trRad.GetY() * 2.f); + float endArcHeight = std::min(height - BOTTOMW, brRad.GetY() * 2.f); + auto rs = Drawing::Rect(x - startArcWidth, y, x, y + startArcHeight); + auto re = Drawing::Rect(x - endArcWidth, height - BOTTOMW2 - endArcHeight, x, height - BOTTOMW2); + // create drawing path from right top corner to right bottom corner + Drawing::Path rightBorder; + rightBorder.MoveTo(x - trRad.GetX() / 2.f, std::min(y, offsetY + trRad.GetY() / 2.f)); + rightBorder.ArcTo(rs.GetLeft(), rs.GetTop(), rs.GetRight(), rs.GetBottom(), RIGHT_START, SWEEP_ANGLE); + rightBorder.ArcTo(re.GetLeft(), re.GetTop(), re.GetRight(), re.GetBottom(), RIGHT_END, SWEEP_ANGLE); + rightBorder.LineTo(x - brRad.GetX() / 2.f, + std::max(offsetY + height - BOTTOMW2, offsetY + height - brRad.GetY() / 2.f)); canvas.AttachPen(pen); - if (style == BorderStyle::SOLID) { - auto r = rightBorder.GetBounds(); - canvas.DrawRect(r); - canvas.DetachPen(); + if (GetStyle(RSBorder::RIGHT) == BorderStyle::SOLID) { Drawing::Brush brush; brush.SetColor(pen.GetColor()); brush.SetAntiAlias(true); canvas.AttachBrush(brush); - r.MakeOutset(-pen.GetWidth() / PARAM_DOUBLE, -pen.GetWidth() / PARAM_DOUBLE); - canvas.DrawRect(r); + canvas.DrawRect(rightBorder.GetBounds()); canvas.DetachBrush(); } else { canvas.DrawPath(rightBorder); - canvas.DetachPen(); } + canvas.DetachPen(); } } void RSBorder::PaintBottomPath(Drawing::Canvas& canvas, Drawing::Pen& pen, const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const { - float offsetX = rrect.GetRect().GetLeft(); - float offsetY = rrect.GetRect().GetTop(); - float width = rrect.GetRect().GetWidth(); - float height = rrect.GetRect().GetHeight(); - auto style = GetStyle(RSBorder::BOTTOM); - float leftW = GetWidth(RSBorder::LEFT); - float topW = GetWidth(RSBorder::TOP); - float rightW = GetWidth(RSBorder::RIGHT); - float bottomW = GetWidth(RSBorder::BOTTOM); - float x = offsetX + leftW / 2.0f; - float y = offsetY + topW / 2.0f; - float w = std::max(0.0f, width - (leftW + rightW) / 2.0f); - float h = std::max(0.0f, height - (topW + bottomW) / 2.0f); - float brX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS).GetX() - (bottomW + rightW) / 4.0f); - float brY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS).GetY() - (bottomW + rightW) / 4.0f); - float blX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS).GetX() - (bottomW + leftW) / 4.0f); - float blY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS).GetY() - (bottomW + leftW) / 4.0f); - if (bottomW > 0.f) { + if (BOTTOMW > 0.f) { + float offsetX = rrect.GetRect().GetLeft(); + float offsetY = rrect.GetRect().GetTop(); + float width = rrect.GetRect().GetWidth(); + float x = offsetX + LEFTW2; + float y = offsetY + rrect.GetRect().GetHeight() - BOTTOMW2; + Drawing::Point brRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS); + Drawing::Point blRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS); ApplyLineStyle(pen, RSBorder::BOTTOM, width); - auto rectStart = Drawing::Rect(x + w - brX * 2.0f, y + h - brY * 2.0f, x + w, y + h); - auto rectEnd = Drawing::Rect(x, y + h - blY * 2.0f, x + blX * 2.0f, y + h); - Drawing::Path bottomBorder; if (GetStyle(RSBorder::BOTTOM) != BorderStyle::DOTTED) { - pen.SetWidth(std::max(std::max(leftW, topW), std::max(rightW, bottomW))); + pen.SetWidth(std::max(std::max(LEFTW, TOPW), std::max(RIGHTW, BOTTOMW))); } Drawing::AutoCanvasRestore acr(canvas, true); - canvas.ClipRect({ offsetX, innerRectCenter.GetY(), offsetX + width, offsetY + height }); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(brX, 0.f) && !ROSEN_EQ(rightW, 0.f))) { - bottomBorder.MoveTo(offsetX + width, offsetY + height - bottomW / 2.0f); - bottomBorder.LineTo(x + w - brX * 2.0f, y + h - brY * 2.0f); - Drawing::Path bottomClipPath; - bottomClipPath.MoveTo(offsetX + width + rightW, offsetY + height + bottomW); - bottomClipPath.LineTo(offsetX + width - rightW * EXTEND, offsetY + height - bottomW * EXTEND); - bottomClipPath.LineTo(offsetX + width, offsetY + height - bottomW * EXTEND); - bottomClipPath.Close(); - bottomClipPath.Offset(0.5, 0); - canvas.ClipPath(bottomClipPath, Drawing::ClipOp::DIFFERENCE, true); - } - bottomBorder.ArcTo(rectStart.GetLeft(), rectStart.GetTop(), rectStart.GetRight(), rectStart.GetBottom(), - BOTTOM_START, SWEEP_ANGLE); - bottomBorder.ArcTo(rectEnd.GetLeft(), rectEnd.GetTop(), rectEnd.GetRight(), rectEnd.GetBottom(), - BOTTOM_END, SWEEP_ANGLE + 0.5f); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(blX, 0.f) && !ROSEN_EQ(leftW, 0.f))) { - bottomBorder.LineTo(offsetX, offsetY + height - bottomW / 2.0f); - Drawing::Path bottomClipPath; - bottomClipPath.MoveTo(offsetX - leftW, offsetY + height + bottomW); - bottomClipPath.LineTo(offsetX + leftW * EXTEND, offsetY + height - bottomW * EXTEND); - bottomClipPath.LineTo(offsetX, offsetY + height - bottomW * EXTEND); - bottomClipPath.Close(); - bottomClipPath.Offset(-0.5, 0); - canvas.ClipPath(bottomClipPath, Drawing::ClipOp::DIFFERENCE, true); - } + // bottom left intersection point with innerRect center + Drawing::Point blip = GetBLIP(rrect, innerRectCenter); + // bottom right intersection point with innerRect center + Drawing::Point brip = GetBRIP(rrect, innerRectCenter); + // draw clipping path for bottom border + Drawing::Path bottomClipPath; + bottomClipPath.MoveTo(offsetX, offsetY + rrect.GetRect().GetHeight()); + bottomClipPath.LineTo(blip.GetX(), blip.GetY()); + bottomClipPath.LineTo(brip.GetX(), brip.GetY()); + bottomClipPath.LineTo(offsetX + width, offsetY + rrect.GetRect().GetHeight()); + bottomClipPath.Close(); + canvas.ClipPath(bottomClipPath, Drawing::ClipOp::INTERSECT, true); + // calc rectangles to draw right bottom and left bottom arcs according to radii values + float startArcWidth = std::min(width - RIGHTW, brRad.GetX() * 2.f); + float endArcWidth = std::min(width - LEFTW, blRad.GetX() * 2.f); + float startArcHeight = std::min(rrect.GetRect().GetHeight() - BOTTOMW, brRad.GetY() * 2.f); + float endArcHeight = std::min(rrect.GetRect().GetHeight() - BOTTOMW, blRad.GetY() * 2.f); + auto rs = Drawing::Rect(offsetX + width - RIGHTW2 - startArcWidth, y - startArcHeight, + offsetX + width - RIGHTW2, y); + auto re = Drawing::Rect(x, y - endArcHeight, x + endArcWidth, y); + // create drawing path from right bottom corner to left bottom corner + Drawing::Path bottomBorder; + bottomBorder.MoveTo(std::max(offsetX + width - RIGHTW2, offsetY + width - brRad.GetX() / 2.f), + y - brRad.GetY() / 2.f); + bottomBorder.ArcTo(rs.GetLeft(), rs.GetTop(), rs.GetRight(), rs.GetBottom(), BOTTOM_START, SWEEP_ANGLE); + bottomBorder.ArcTo(re.GetLeft(), re.GetTop(), re.GetRight(), re.GetBottom(), BOTTOM_END, SWEEP_ANGLE); + bottomBorder.LineTo(std::min(x, offsetX + blRad.GetX() / 2.f), y - blRad.GetY() / 2.f); canvas.AttachPen(pen); - if (style == BorderStyle::SOLID) { - auto r = bottomBorder.GetBounds(); - canvas.DrawRect(r); - canvas.DetachPen(); + if (GetStyle(RSBorder::BOTTOM) == BorderStyle::SOLID) { Drawing::Brush brush; brush.SetColor(pen.GetColor()); brush.SetAntiAlias(true); canvas.AttachBrush(brush); - r.MakeOutset(-pen.GetWidth() / PARAM_DOUBLE, -pen.GetWidth() / PARAM_DOUBLE); - canvas.DrawRect(r); + canvas.DrawRect(bottomBorder.GetBounds()); canvas.DetachBrush(); } else { canvas.DrawPath(bottomBorder); - canvas.DetachPen(); } + canvas.DetachPen(); } } void RSBorder::PaintLeftPath(Drawing::Canvas& canvas, Drawing::Pen& pen, const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const { - float offsetX = rrect.GetRect().GetLeft(); - float offsetY = rrect.GetRect().GetTop(); - float height = rrect.GetRect().GetHeight(); - auto style = GetStyle(RSBorder::LEFT); - float leftW = GetWidth(RSBorder::LEFT); - float topW = GetWidth(RSBorder::TOP); - float rightW = GetWidth(RSBorder::RIGHT); - float bottomW = GetWidth(RSBorder::BOTTOM); - float x = offsetX + leftW / 2.0f; - float y = offsetY + topW / 2.0f; - float h = std::max(0.0f, height - (topW + bottomW) / 2.0f); - float tlX = std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS).GetX() - (topW + leftW) / 4.0f); - float tlY = std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS).GetY() - (topW + leftW) / 4.0f); - float blX = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS).GetX() - (bottomW + leftW) / 4.0f); - float blY = - std::max(0.0f, rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS).GetY() - (bottomW + leftW) / 4.0f); - if (leftW > 0.f) { + if (LEFTW > 0.f) { + float offsetX = rrect.GetRect().GetLeft(); + float offsetY = rrect.GetRect().GetTop(); + float height = rrect.GetRect().GetHeight(); + float x = offsetX + LEFTW2; + float y = offsetY + TOPW2; + Drawing::Point tlRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS); + Drawing::Point blRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS); ApplyLineStyle(pen, RSBorder::LEFT, height); - auto rectStart = Drawing::Rect(x, y + h - blY * 2.0f, x + blX * 2.0f, y + h); - auto rectEnd = Drawing::Rect(x, y, x + tlX * 2.0f, y + tlY * 2.0f); - Drawing::Path leftBorder; if (GetStyle(RSBorder::LEFT) != BorderStyle::DOTTED) { - pen.SetWidth(std::max(std::max(leftW, topW), std::max(rightW, bottomW))); + pen.SetWidth(std::max(std::max(LEFTW, TOPW), std::max(RIGHTW, BOTTOMW))); } Drawing::AutoCanvasRestore acr(canvas, true); - canvas.ClipRect({ offsetX, offsetY, innerRectCenter.GetX(), offsetY + height }); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(blX, 0.f) && !ROSEN_EQ(bottomW, 0.f))) { - leftBorder.MoveTo(offsetX + leftW / 2.0f, offsetY + height); - leftBorder.LineTo(x, y + h - blY * 2.0f); - Drawing::Path leftClipPath; - leftClipPath.MoveTo(offsetX - leftW, offsetY + height + bottomW); - leftClipPath.LineTo(offsetX + leftW * EXTEND, offsetY + height - bottomW * EXTEND); - leftClipPath.LineTo(offsetX + leftW * EXTEND, offsetY + height); - leftClipPath.Close(); - leftClipPath.Offset(0, 0.5); - canvas.ClipPath(leftClipPath, Drawing::ClipOp::DIFFERENCE, true); - } - - leftBorder.ArcTo(rectStart.GetLeft(), rectStart.GetTop(), rectStart.GetRight(), rectStart.GetBottom(), - LEFT_START, SWEEP_ANGLE); - leftBorder.ArcTo(rectEnd.GetLeft(), rectEnd.GetTop(), rectEnd.GetRight(), rectEnd.GetBottom(), - LEFT_END, SWEEP_ANGLE + 0.5f); - if ((style == BorderStyle::SOLID) || (ROSEN_EQ(tlX, 0.f) && !ROSEN_EQ(topW, 0.f))) { - leftBorder.LineTo(offsetX + leftW / 2.0f, offsetY); - Drawing::Path leftClipPath; - leftClipPath.MoveTo(offsetX - leftW, offsetY - topW); - leftClipPath.LineTo(offsetX + leftW * EXTEND, offsetY + topW * EXTEND); - leftClipPath.LineTo(offsetX + leftW * EXTEND, offsetY); - leftClipPath.Close(); - leftClipPath.Offset(0, -0.5); - canvas.ClipPath(leftClipPath, Drawing::ClipOp::DIFFERENCE, true); - } + Drawing::Path leftClipPath; + // top left intersection point with innerRect center + Drawing::Point tlip = GetTLIP(rrect, innerRectCenter); + // bottom left intersection point with innerRect center + Drawing::Point blip = GetBLIP(rrect, innerRectCenter); + // draw clipping path for left border + leftClipPath.MoveTo(offsetX, offsetY); + leftClipPath.LineTo(tlip.GetX(), tlip.GetY()); + leftClipPath.LineTo(blip.GetX(), blip.GetY()); + leftClipPath.LineTo(offsetX, offsetY + height); + leftClipPath.Close(); + canvas.ClipPath(leftClipPath, Drawing::ClipOp::INTERSECT, true); + // calc rectangles to draw left bottom and left top arcs according to radii values + float startArcWidth = std::min(rrect.GetRect().GetWidth() - LEFTW, blRad.GetX() * 2.f); + float endArcWidth = std::min(rrect.GetRect().GetWidth() - LEFTW, tlRad.GetX() * 2.f); + float startArcHeight = std::min(height - BOTTOMW, blRad.GetY() * 2.f); + float endArcHeight = std::min(height - TOPW, tlRad.GetY() * 2.f); + auto rs = Drawing::Rect(x, offsetY + height - BOTTOMW2 - startArcHeight, + x + startArcWidth, offsetY + height - BOTTOMW2); + auto re = Drawing::Rect(x, y, x + endArcWidth, y + endArcHeight); + // create drawing path from left bottom corner to left top corner + Drawing::Path leftBorder; + leftBorder.MoveTo(x + blRad.GetX() / 2.f, std::max(offsetY + height - BOTTOMW2, + offsetY + height - blRad.GetY() / 2.f)); + leftBorder.ArcTo(rs.GetLeft(), rs.GetTop(), rs.GetRight(), rs.GetBottom(), LEFT_START, SWEEP_ANGLE); + leftBorder.ArcTo(re.GetLeft(), re.GetTop(), re.GetRight(), re.GetBottom(), LEFT_END, SWEEP_ANGLE); + leftBorder.LineTo(x + tlRad.GetX() / 2.f, std::min(y, offsetY + tlRad.GetY() / 2.f)); canvas.AttachPen(pen); - if (style == BorderStyle::SOLID) { - auto r = leftBorder.GetBounds(); - canvas.DrawRect(r); - canvas.DetachPen(); + if (GetStyle(RSBorder::LEFT) == BorderStyle::SOLID) { Drawing::Brush brush; brush.SetColor(pen.GetColor()); brush.SetAntiAlias(true); canvas.AttachBrush(brush); - r.MakeOutset(-pen.GetWidth() / PARAM_DOUBLE, -pen.GetWidth() / PARAM_DOUBLE); - canvas.DrawRect(r); + canvas.DrawRect(leftBorder.GetBounds()); canvas.DetachBrush(); } else { canvas.DrawPath(leftBorder); - canvas.DetachPen(); } + canvas.DetachPen(); } } +// Return top left intersection pos for clipping +Drawing::Point RSBorder::GetTLIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const +{ + // inner round rect center point + float x = innerRectCenter.GetX(); + float y = innerRectCenter.GetY(); + // width/height of inner round rect + float width = rrect.GetRect().GetWidth() - LEFTW - RIGHTW; + float height = rrect.GetRect().GetHeight() - TOPW - BOTTOMW; + if (width > 0) { + // kc is linear ratio of inner rect + float kc = height / width; + if (LEFTW > 0) { + // k is linear ratio for external rect (cutting angle at top left corner) + float k = TOPW / LEFTW; + // raduii values of external round rect for calculating clipping point + Drawing::Point tlRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS); + Drawing::Point trRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS); + Drawing::Point blRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS); + // shows what center axis of inner round rect we intersect fist (x or y) + if (k <= kc) { + // top left and right raduii for inner round rect + float dlx = std::max(tlRad.GetX() - LEFTW, 0.f); + float drx = std::max(trRad.GetX() - RIGHTW, 0.f); + // calc delta to prevent overlapping of top right corner + x = (dlx > 0) ? (x + std::min(dlx, width / 2.f - drx)) : (x - width / 2.f); + y = x * k; + } else { + // left top and bottom raduii for inner round rect + float dty = std::max(tlRad.GetY() - TOPW, 0.f); + float dby = std::max(blRad.GetY() - BOTTOMW, 0.f); + // calc delta to prevent overlapping of bottom left corner + y = (dty > 0) ? (y = y + std::min(dty, height / 2.f - dby)) : (y - height / 2.f); + x = y / k; + } + } else { + x = rrect.GetRect().GetLeft(); + y = std::max(y - height / 2.f, rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() / 2.f); + } + } else { + y = rrect.GetRect().GetTop() + TOPW; + } + return Drawing::Point(x, y); +} + +// Return top right intersection pos for clipping +Drawing::Point RSBorder::GetTRIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const +{ + // inner round rect center point + float x = innerRectCenter.GetX(); + float y = innerRectCenter.GetY(); + // width/height of inner round rect + float width = rrect.GetRect().GetWidth() - LEFTW - RIGHTW; + float height = rrect.GetRect().GetHeight() - TOPW - BOTTOMW; + if (width > 0) { + // kc is linear ratio of inner rect + float kc = height / width; + if (RIGHTW > 0) { + // k is linear ratio for external rect (cutting angle at top right corner) + float k = TOPW / RIGHTW; + // raduii values of external round rect for calculating clipping point + Drawing::Point trRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS); + Drawing::Point tlRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS); + Drawing::Point brRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS); + // shows what center axis of inner round rect we intersect fist (x or y) + if (k <= kc) { + // top left and right raduii for inner round rect + float drx = std::max(trRad.GetX() - RIGHTW, 0.f); + float dlx = std::max(tlRad.GetX() - LEFTW, 0.f); + // calc delta to prevent overlapping of top left corner + x = (drx > 0) ? (x - std::min(drx, width / 2.f - dlx)) : (x + width / 2.f); + y = (rrect.GetRect().GetWidth() - x) * k; + } else { + // right top and bottom raduii for inner round rect + float dty = std::max(trRad.GetY() - TOPW, 0.f); + float dby = std::max(brRad.GetY() - BOTTOMW, 0.f); + // calc delta to prevent overlapping of bottom right corner + y = (dty > 0) ? (y = y + std::min(dty, height / 2.f - dby)) : (y - height / 2.f); + x = rrect.GetRect().GetWidth() - y / k; + } + } else { + x = rrect.GetRect().GetLeft() + rrect.GetRect().GetWidth(); + y = std::max(y - height / 2.f, rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() / 2.f); + } + } else { + y = rrect.GetRect().GetTop() + TOPW; + } + return Drawing::Point(x, y); +} + +// Return bottom left intersection pos for clipping +Drawing::Point RSBorder::GetBLIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const +{ + // inner round rect center point + float x = innerRectCenter.GetX(); + float y = innerRectCenter.GetY(); + // width/height of inner round rect + float width = rrect.GetRect().GetWidth() - LEFTW - RIGHTW; + float height = rrect.GetRect().GetHeight() - TOPW - BOTTOMW; + if (width > 0) { + // kc is linear ratio of inner rect + float kc = height / width; + if (LEFTW > 0) { + // k is linear ratio for external rect (cutting angle at bottom left corner) + float k = BOTTOMW / LEFTW; + // raduii values of external round rect for calculating clipping point + Drawing::Point blRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS); + Drawing::Point tlRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_LEFT_POS); + Drawing::Point brRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS); + // shows what center axis of inner round rect we intersect fist (x or y) + if (k <= kc) { + // bottom left and right raduii for inner round rect + float dlx = std::max(blRad.GetX() - LEFTW, 0.f); + float drx = std::max(brRad.GetX() - RIGHTW, 0.f); + // calc delta to prevent overlapping of bottom right corner + x = (dlx > 0) ? (x + std::min(dlx, width / 2.f - drx)) : (x - width / 2.f); + y = rrect.GetRect().GetHeight() - x * k; + } else { + // left bottom and top raduii for inner round rect + float dby = std::max(blRad.GetY() - BOTTOMW, 0.f); + float dty = std::max(tlRad.GetY() - TOPW, 0.f); + // calc delta to prevent overlapping of top left corner + y = (dby > 0) ? (y = y - std::min(dby, height / 2.f - dty)) : (y + height / 2.f); + x = (rrect.GetRect().GetHeight() - y) / k; + } + } else { + x = rrect.GetRect().GetLeft(); + y = std::min(y + height / 2.f, + std::max(rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() / 2.f, + rrect.GetRect().GetTop() + TOPW)); + } + } else { + y = rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() - BOTTOMW; + } + return Drawing::Point(x, y); +} + +// Return bottom right intersection pos for clipping +Drawing::Point RSBorder::GetBRIP(const Drawing::RoundRect& rrect, const Drawing::Point& innerRectCenter) const +{ + // inner round rect center point + float x = innerRectCenter.GetX(); + float y = innerRectCenter.GetY(); + // width/height of inner round rect + float width = rrect.GetRect().GetWidth() - LEFTW - RIGHTW; + float height = rrect.GetRect().GetHeight() - TOPW - BOTTOMW; + if (width > 0) { + // kc is linear ratio of inner rect + float kc = height / width; + if (RIGHTW > 0) { + // k is linear ratio for external rect (cutting angle at bottom right corner) + float k = BOTTOMW / RIGHTW; + // raduii values of external round rect for calculating clipping point + Drawing::Point brRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_RIGHT_POS); + Drawing::Point blRad = rrect.GetCornerRadius(Drawing::RoundRect::BOTTOM_LEFT_POS); + Drawing::Point trRad = rrect.GetCornerRadius(Drawing::RoundRect::TOP_RIGHT_POS); + // shows what center axis of inner round rect we intersect fist (x or y) + if (k <= kc) { + // bottom left and right raduii for inner round rect + float drx = std::max(brRad.GetX() - RIGHTW, 0.f); + float dlx = std::max(blRad.GetX() - LEFTW, 0.f); + // calc delta to prevent overlapping of bottom left corner + x = (drx > 0) ? (x - std::min(drx, width / 2.f - dlx)) : (x + width / 2.f); + y = rrect.GetRect().GetHeight() - (rrect.GetRect().GetWidth() - x) * k; + } else { + // right bottom and top raduii for inner round rect + float dby = std::max(brRad.GetY() - BOTTOMW, 0.f); + float dty = std::max(trRad.GetY() - TOPW, 0.f); + // calc delta to prevent overlapping of top right corner + y = (dby > 0) ? (y = y - std::min(dby, height / 2.f - dty)) : (y + height / 2.f); + x = rrect.GetRect().GetWidth() - (rrect.GetRect().GetHeight() - y) / k; + } + } else { + x = rrect.GetRect().GetLeft() + rrect.GetRect().GetWidth(); + y = std::min(y + height / 2.f, + std::max(rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() / 2.f, + rrect.GetRect().GetTop() + TOPW)); + } + } else { + y = rrect.GetRect().GetTop() + rrect.GetRect().GetHeight() - BOTTOMW; + } + return Drawing::Point(x, y); +} + std::string RSBorder::ToString() const { std::stringstream ss; diff --git a/rosen/modules/render_service_base/src/render/rs_foreground_effect_filter.cpp b/rosen/modules/render_service_base/src/render/rs_foreground_effect_filter.cpp index 1ebb917799..61b3086bf3 100644 --- a/rosen/modules/render_service_base/src/render/rs_foreground_effect_filter.cpp +++ b/rosen/modules/render_service_base/src/render/rs_foreground_effect_filter.cpp @@ -78,9 +78,7 @@ void RSForegroundEffectFilter::ComputeParamter(int radius) { static constexpr int noiseFactor = 3; // 3 : smooth the radius change blurRadius_ = radius * 4 / noiseFactor * noiseFactor; // 4 : scale between gauss radius and kawase - if (blurRadius_ > BLUR_RADIUS_LIMIT) { - blurRadius_ = BLUR_RADIUS_LIMIT; - } + blurRadius_ = std::clamp(blurRadius_, 0.f, BLUR_RADIUS_LIMIT); AdjustRadiusAndScale(); ComputePassesAndUnit(); } diff --git a/rosen/modules/render_service_base/src/render/rs_kawase_blur.cpp b/rosen/modules/render_service_base/src/render/rs_kawase_blur.cpp index 481ae5fb9a..343a683681 100644 --- a/rosen/modules/render_service_base/src/render/rs_kawase_blur.cpp +++ b/rosen/modules/render_service_base/src/render/rs_kawase_blur.cpp @@ -224,8 +224,6 @@ bool KawaseBlurFilter::ApplyKawaseBlur(Drawing::Canvas& canvas, const std::share OutputOriginalImage(canvas, image, param); return true; } - auto src = param.src; - auto dst = param.dst; auto input = image; CheckInputImage(canvas, image, param, input); ComputeRadiusAndScale(param.radius); @@ -233,21 +231,32 @@ bool KawaseBlurFilter::ApplyKawaseBlur(Drawing::Canvas& canvas, const std::share int maxPasses = supportLargeRadius ? kMaxPassesLargeRadius : kMaxPasses; float dilatedConvolutionFactor = supportLargeRadius ? kDilatedConvolutionLargeRadius : kDilatedConvolution; if (abs(dilatedConvolutionFactor) <= 1e-6) { - return false; + dilatedConvolutionFactor = 4.6f; // 4.6 : radio between gauss and kawase } float tmpRadius = static_cast(blurRadius_) / dilatedConvolutionFactor; int numberOfPasses = std::min(maxPasses, std::max(static_cast(ceil(tmpRadius)), 1)); // 1 : min pass num float radiusByPasses = tmpRadius / numberOfPasses; ROSEN_LOGD("KawaseBlurFilter::kawase radius : %{public}f, scale : %{public}f, pass num : %{public}d", blurRadius_, blurScale_, numberOfPasses); + int width = std::max(static_cast(std::ceil(param.dst.GetWidth())), input->GetWidth()); + int height = std::max(static_cast(std::ceil(param.dst.GetHeight())), input->GetHeight()); + auto blurParams = BlurParams{numberOfPasses, width, height, radiusByPasses}; + auto blurImage = ExecutePingPongBlur(canvas, input, param, blurParams); + RS_OPTIONAL_TRACE_END(); + if (!blurImage) { + return false; + } + return ApplyBlur(canvas, input, blurImage, param); +} - auto width = std::max(static_cast(std::ceil(dst.GetWidth())), input->GetWidth()); - auto height = std::max(static_cast(std::ceil(dst.GetHeight())), input->GetHeight()); +std::shared_ptr KawaseBlurFilter::ExecutePingPongBlur(Drawing::Canvas& canvas, + const std::shared_ptr& input, const KawaseParameter& inParam, const BlurParams& blur) const +{ auto originImageInfo = input->GetImageInfo(); - auto scaledInfo = Drawing::ImageInfo(std::ceil(width * blurScale_), std::ceil(height * blurScale_), + auto scaledInfo = Drawing::ImageInfo(std::ceil(blur.width * blurScale_), std::ceil(blur.height * blurScale_), originImageInfo.GetColorType(), originImageInfo.GetAlphaType(), originImageInfo.GetColorSpace()); Drawing::Matrix blurMatrix; - blurMatrix.Translate(-src.GetLeft(), -src.GetTop()); + blurMatrix.Translate(-inParam.src.GetLeft(), -inParam.src.GetTop()); float scaleW = static_cast(scaledInfo.GetWidth()) / input->GetWidth(); float scaleH = static_cast(scaledInfo.GetHeight()) / input->GetHeight(); blurMatrix.PostScale(scaleW, scaleH); @@ -261,20 +270,20 @@ bool KawaseBlurFilter::ApplyKawaseBlur(Drawing::Canvas& canvas, const std::share if (isUsingAF) { SkV2 firstPassOffsets[BLUR_SAMPLE_COUNT]; - OffsetInfo firstPassOffsetInfo = {radiusByPasses * blurScale_, radiusByPasses * blurScale_, + OffsetInfo firstPassOffsetInfo = {blur.radiusByPass * blurScale_, blur.radiusByPass * blurScale_, scaledInfo.GetWidth(), scaledInfo.GetHeight()}; getNormalizedOffset(firstPassOffsets, BLUR_SAMPLE_COUNT, firstPassOffsetInfo); blurBuilder.SetUniform("in_blurOffset", firstPassOffsetInfo.offsetX, firstPassOffsetInfo.offsetY, firstPassOffsetInfo.width, firstPassOffsetInfo.height); } else { - blurBuilder.SetUniform("in_blurOffset", radiusByPasses * blurScale_, radiusByPasses * blurScale_); - blurBuilder.SetUniform("in_maxSizeXY", width * blurScale_, height * blurScale_); + blurBuilder.SetUniform("in_blurOffset", blur.radiusByPass * blurScale_, blur.radiusByPass * blurScale_); + blurBuilder.SetUniform("in_maxSizeXY", blur.width * blurScale_, blur.height * blurScale_); } std::shared_ptr tmpBlur(blurBuilder.MakeImage( canvas.GetGPUContext().get(), nullptr, scaledInfo, false)); // And now we'll build our chain of scaled blur stages - for (auto i = 1; i < numberOfPasses; i++) { + for (auto i = 1; i < blur.numberOfPasses; i++) { const float stepScale = static_cast(i) * blurScale_; blurBuilder.SetChild("imageInput", Drawing::ShaderEffect::CreateImageShader(*tmpBlur, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, Drawing::Matrix())); @@ -282,19 +291,18 @@ bool KawaseBlurFilter::ApplyKawaseBlur(Drawing::Canvas& canvas, const std::share // Advanced Filter if (isUsingAF) { SkV2 offsets[BLUR_SAMPLE_COUNT]; - OffsetInfo offsetInfo = {radiusByPasses * stepScale, radiusByPasses * stepScale, + OffsetInfo offsetInfo = {blur.radiusByPass * stepScale, blur.radiusByPass * stepScale, scaledInfo.GetWidth(), scaledInfo.GetHeight()}; getNormalizedOffset(offsets, BLUR_SAMPLE_COUNT, offsetInfo); blurBuilder.SetUniform("in_blurOffset", offsetInfo.offsetX, offsetInfo.offsetY, offsetInfo.width, offsetInfo.height); } else { - blurBuilder.SetUniform("in_blurOffset", radiusByPasses * stepScale, radiusByPasses * stepScale); - blurBuilder.SetUniform("in_maxSizeXY", width * blurScale_, height * blurScale_); + blurBuilder.SetUniform("in_blurOffset", blur.radiusByPass * stepScale, blur.radiusByPass * stepScale); + blurBuilder.SetUniform("in_maxSizeXY", blur.width * blurScale_, blur.height * blurScale_); } tmpBlur = blurBuilder.MakeImage(canvas.GetGPUContext().get(), nullptr, scaledInfo, false); } - RS_OPTIONAL_TRACE_END(); - return ApplyBlur(canvas, input, tmpBlur, param); + return tmpBlur; } bool KawaseBlurFilter::ApplyBlur(Drawing::Canvas& canvas, const std::shared_ptr& image, diff --git a/rosen/modules/render_service_base/src/render/rs_mask.cpp b/rosen/modules/render_service_base/src/render/rs_mask.cpp index 7e7cc8b38f..22b3960fb6 100644 --- a/rosen/modules/render_service_base/src/render/rs_mask.cpp +++ b/rosen/modules/render_service_base/src/render/rs_mask.cpp @@ -238,18 +238,6 @@ bool RSMask::Marshalling(Parcel& parcel) const return false; } - if (IsSvgMask()) { - ROSEN_LOGD("SVG RSMask::Marshalling"); - SkPictureRecorder recorder; - SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::MakeSize(svgDom_->containerSize())); - svgDom_->render(recordingCanvas); - sk_sp picture = recorder.finishRecordingAsPicture(); - if (!RSMarshallingHelper::Marshalling(parcel, picture)) { - ROSEN_LOGE("RSMask::Marshalling SkPicture failed!"); - return false; - } - } - if (IsPixelMapMask() && !RSMarshallingHelper::Marshalling(parcel, pixelMap_)) { ROSEN_LOGE("RSMask::Marshalling Pixelmap failed!"); return false; @@ -322,14 +310,6 @@ RSMask* RSMask::Unmarshalling(Parcel& parcel) maskCmdList->Playback(rsMask->maskPath_, rsMask->maskPen_, rsMask->maskBrush_); } - if (rsMask->IsSvgMask()) { - ROSEN_LOGD("SVG RSMask::Unmarshalling"); - if (!RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgPicture_)) { - ROSEN_LOGE("RSMask::Unmarshalling SkPicture failed!"); - return nullptr; - } - } - if (rsMask->IsPixelMapMask() && !RSMarshallingHelper::Unmarshalling(parcel, rsMask->pixelMap_)) { ROSEN_LOGE("RSMask::Unmarshalling pixelmap failed!"); return nullptr; diff --git a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_animation_test.cpp b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_animation_test.cpp index b88432d08d..e3e32d1903 100644 --- a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_animation_test.cpp +++ b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_animation_test.cpp @@ -16,7 +16,6 @@ #include #include "gtest/gtest.h" -#include "animation/rs_render_particle.h" #include "animation/rs_render_particle_animation.h" #include "common/rs_vector2.h" #include "modifier/rs_render_property.h" diff --git a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_effector_test.cpp b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_effector_test.cpp index 33275e642a..91e1219965 100644 --- a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_effector_test.cpp +++ b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_effector_test.cpp @@ -18,7 +18,6 @@ #include "gtest/gtest.h" -#include "animation/rs_render_particle.h" #include "animation/rs_render_particle_animation.h" #include "animation/rs_cubic_bezier_interpolator.h" #include "common/rs_vector2.h" @@ -79,6 +78,7 @@ void RSRenderParticleEffectorTest::SetColor() Color start = RSColor(200, 0, 0, 100); Color end = RSColor(255, 255, 255, 255); Range colorVal = Range(start, end); + DistributionType distribution = DistributionType::UNIFORM; ParticleUpdator colorUpdator = ParticleUpdator::RANDOM; Range redRandom = Range(0.1f, 1.f); Range greenRandom = Range(0.1f, 1.f); @@ -86,7 +86,7 @@ void RSRenderParticleEffectorTest::SetColor() Range alphaRandom = Range(0.1f, 1.f); std::vector>> colorChangeOverLife = {}; color_ = RenderParticleColorParaType( - colorVal, colorUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); + colorVal, distribution, colorUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); } void RSRenderParticleEffectorTest::SetOpacity() @@ -196,8 +196,8 @@ HWTEST_F(RSRenderParticleEffectorTest, UpdateEffect001, TestSize.Level1) Range blueRandom = Range(-1.0f, 0.f); Range alphaRandom = Range(-1.0f, 0.f); std::vector>> colorChangeOverLife = {}; - RenderParticleColorParaType color = RenderParticleColorParaType( - colorVal, randomUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); + RenderParticleColorParaType color = RenderParticleColorParaType(colorVal, DistributionType::UNIFORM, + randomUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); Range opacityVal = Range(0.5f, 1.0f); Range randomSpeed = Range(0.1f, 1.f); Range opacityRandom; @@ -264,6 +264,7 @@ HWTEST_F(RSRenderParticleEffectorTest, UpdateColorCurve001, TestSize.Level1) Color start = RSColor(255, 255, 255, 255); Color end = RSColor(255, 255, 255, 255); Range colorVal = Range(start, end); + DistributionType distribution = DistributionType::UNIFORM; ParticleUpdator curveUpdator = ParticleUpdator::CURVE; Range redRandom = Range(-1.0f, 0.f); Range greenRandom = Range(-1.0f, 0.f); @@ -280,7 +281,7 @@ HWTEST_F(RSRenderParticleEffectorTest, UpdateColorCurve001, TestSize.Level1) std::make_shared>(colorFromValue, colorToValue, startMillis, endMillis, interpolator); colorChangeOverLife.push_back(colorChange); RenderParticleColorParaType color = RenderParticleColorParaType( - colorVal, curveUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); + colorVal, distribution, curveUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); params = std::make_shared(emitterConfig, velocity, acceleration, color, opacity, scale, spin); particle = std::make_shared(params); std::vector> particles; @@ -299,18 +300,6 @@ HWTEST_F(RSRenderParticleEffectorTest, UpdateColorCurve001, TestSize.Level1) HWTEST_F(RSRenderParticleEffectorTest, UpdateAccelerationRandom001, TestSize.Level1) { GTEST_LOG_(INFO) << "RSRenderParticleEffectorTest UpdateAccelerationRandom001 start"; - int emitRate = 20; - ShapeType emitShape = ShapeType::RECT; - Vector2f position = Vector2f(0.f, 0.f); - Vector2f emitSize = Vector2f(10.f, 10.f); - int particleCount = 20; - Range lifeTime = Range(3000, 3000); // 3000 is lifeTime. - ParticleType type = ParticleType::POINTS; - float radius = 1; - std::shared_ptr image; - Vector2f imageSize = Vector2f(1.f, 1.f); - EmitterConfig emitterConfig = - EmitterConfig(emitRate, emitShape, position, emitSize, particleCount, lifeTime, type, radius, image, imageSize); ParticleVelocity velocity; RenderParticleAcceleration acceleration; RenderParticleParaType opacity; @@ -329,13 +318,24 @@ HWTEST_F(RSRenderParticleEffectorTest, UpdateAccelerationRandom001, TestSize.Lev RenderParticleParaType accelerationAngle = RenderParticleParaType(val, randomUpdator, randomSpeed, valChangeOverLife); acceleration = RenderParticleAcceleration(accelerationValue, accelerationAngle); - params = std::make_shared(emitterConfig, velocity, acceleration, color, opacity, scale, spin); + params = + std::make_shared(emitterConfig_, velocity, acceleration, color, opacity, scale, spin); particle = std::make_shared(params); particle->SetActiveTime(activeTime); std::vector> particles; particles.push_back(particle); effector = std::make_shared(); - effector->Update(particle, activeTime); + int fieldStrength = 10; + ShapeType fieldShape = ShapeType::RECT; + Vector2f fieldSize = { 200.f, 200.f }; + Vector2f fieldCenter = { 40.f, 50.f }; + uint16_t fieldFeather = 50; + float noiseScale = 8.f; + float noiseFrequency = 2.f; + float noiseAmplitude = 4.f; + auto particleNoiseField = std::make_shared(fieldStrength, fieldShape, fieldSize, + fieldCenter, fieldFeather, noiseScale, noiseFrequency, noiseAmplitude); + effector->Update(particle, particleNoiseField, activeTime); EXPECT_TRUE(particle->GetActiveTime() == 200000); GTEST_LOG_(INFO) << "RSRenderParticleEffectorTest UpdateAccelerationRandom001 end"; } diff --git a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_emitter_test.cpp b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_emitter_test.cpp index b36fa52b06..182867612e 100644 --- a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_emitter_test.cpp +++ b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_emitter_test.cpp @@ -17,7 +17,6 @@ #include "gtest/gtest.h" -#include "animation/rs_render_particle.h" #include "animation/rs_render_particle_animation.h" #include "animation/rs_render_particle_emitter.h" #include "common/rs_vector2.h" @@ -74,6 +73,7 @@ void RSRenderParticleEmitterTest::SetColor() Color start = RSColor(200, 0, 0, 100); Color end = RSColor(255, 255, 255, 255); Range colorVal = Range(start, end); + DistributionType distribution = DistributionType::UNIFORM; ParticleUpdator colorUpdator = ParticleUpdator::RANDOM; Range redRandom = Range(0.1f, 1.f); Range greenRandom = Range(0.1f, 1.f); @@ -81,7 +81,7 @@ void RSRenderParticleEmitterTest::SetColor() Range alphaRandom = Range(0.1f, 1.f); std::vector>> colorChangeOverLife = {}; color_ = RenderParticleColorParaType( - colorVal, colorUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); + colorVal, distribution, colorUpdator, redRandom, greenRandom, blueRandom, alphaRandom, colorChangeOverLife); } void RSRenderParticleEmitterTest::SetOpacity() diff --git a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_test.cpp b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_test.cpp index a03e5149eb..479c4390ac 100644 --- a/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_test.cpp +++ b/rosen/modules/render_service_base/test/unittest/animation/rs_render_particle_test.cpp @@ -18,7 +18,6 @@ #include "gtest/gtest.h" #include "pixel_map.h" -#include "animation/rs_render_particle.h" #include "animation/rs_render_particle_animation.h" #include "common/rs_vector2.h" #include "modifier/rs_render_property.h" diff --git a/rosen/modules/render_service_client/core/animation/rs_particle_params.h b/rosen/modules/render_service_client/core/animation/rs_particle_params.h index 51392271eb..bb5a028a94 100644 --- a/rosen/modules/render_service_client/core/animation/rs_particle_params.h +++ b/rosen/modules/render_service_client/core/animation/rs_particle_params.h @@ -99,6 +99,7 @@ public: class RSB_EXPORT ParticleColorParaType { public: Range colorVal_; + DistributionType distribution_; ParticleUpdator updator_; Range redRandom_; Range greenRandom_; @@ -106,11 +107,12 @@ public: Range alphaRandom_; std::vector> valChangeOverLife_; - ParticleColorParaType(const Range& colorVal, const ParticleUpdator& updator, const Range& redRandom, - const Range& greenRandom, const Range& blueRandom, const Range& alphaRandom, - std::vector>& valChangeOverLife) + ParticleColorParaType(const Range& colorVal, const DistributionType& distribution, + const ParticleUpdator& updator, const Range& redRandom, const Range& greenRandom, + const Range& blueRandom, const Range& alphaRandom, std::vector>& valChangeOverLife) { colorVal_ = colorVal; + distribution_ = distribution; updator_ = updator; redRandom_ = redRandom; greenRandom_ = greenRandom; @@ -122,8 +124,8 @@ public: } } ParticleColorParaType() - : colorVal_(), updator_(ParticleUpdator::NONE), redRandom_(), greenRandom_(), blueRandom_(), alphaRandom_(), - valChangeOverLife_(0) + : colorVal_(), distribution_(DistributionType::UNIFORM), updator_(ParticleUpdator::NONE), redRandom_(), + greenRandom_(), blueRandom_(), alphaRandom_(), valChangeOverLife_(0) {} ParticleColorParaType(const ParticleColorParaType& velocity) = default; ParticleColorParaType& operator=(const ParticleColorParaType& velocity) = default; @@ -189,6 +191,7 @@ public: { RenderParticleColorParaType color; color.colorVal_ = val.colorVal_; + color.distribution_ = val.distribution_; color.updator_ = val.updator_; if (color.updator_ == ParticleUpdator::RANDOM) { color.redRandom_ = val.redRandom_; diff --git a/rosen/modules/render_service_client/core/animation/rs_symbol_animation.cpp b/rosen/modules/render_service_client/core/animation/rs_symbol_animation.cpp index a4a597870f..4b62c96245 100644 --- a/rosen/modules/render_service_client/core/animation/rs_symbol_animation.cpp +++ b/rosen/modules/render_service_client/core/animation/rs_symbol_animation.cpp @@ -22,9 +22,6 @@ namespace OHOS { namespace Rosen { static const Vector2f CENTER_NODE_COORDINATE = { 0.5f, 0.5f }; // scale center node -static const unsigned int UNIT_GROUP = 0; // AnimationSubType is UNIT -static const unsigned int UNIT_PERIOD = 0; // AnimationSubType is UNIT -static const unsigned int UNIT_NODE = 0; // AnimationSubType is UNIT static const std::string SCALE_PROP_X = "sx"; static const std::string SCALE_PROP_Y = "sy"; static const std::string ALPHA_PROP = "alpha"; @@ -34,57 +31,7 @@ static const unsigned int PROP_END = 1; // symbol animation property contains static const unsigned int WIDTH = 2; static const unsigned int HEIGHT = 3; -bool IsEqual(const Vector2f& val1, const Vector2f& val2) -{ - return (val1.x_ == val2.x_ && val1.y_ == val2.y_); -} - -void CreateAnimationTimingCurve(OHOS::Rosen::Drawing::DrawingCurveType type, std::map& curveArgs, - RSAnimationTimingCurve& curve) -{ - curve = RSAnimationTimingCurve(); - if (type == OHOS::Rosen::Drawing::DrawingCurveType::LINEAR) { - curve = RSAnimationTimingCurve::LINEAR; - } else if (type == OHOS::Rosen::Drawing::DrawingCurveType::SPRING) { - double scaleVelocity = curveArgs.count("velocity") > 0 ? curveArgs["velocity"] : 0; - double scaleMass = curveArgs.count("mass") > 0 ? curveArgs["mass"] : 0; - double scaleStiffness = curveArgs.count("stiffness") > 0 ? curveArgs["stiffness"] : 0; - double scaleDamping = curveArgs.count("damping") > 0 ? curveArgs["damping"] : 0; - curve = RSAnimationTimingCurve::CreateInterpolatingSpring(static_cast(scaleMass), - static_cast(scaleStiffness), static_cast(scaleDamping), static_cast(scaleVelocity)); - } else { - return; - } -} - -bool GetAnimationGroupParameters(const std::shared_ptr& symbolAnimationConfig, - std::vector>& parameters) -{ - // count animation levels - int animationLevelNum = -1; - auto nodeNum = symbolAnimationConfig->numNodes; - for (uint32_t n = 0; n < nodeNum; n++) { - auto& symbolNode = symbolAnimationConfig->SymbolNodes[n]; - animationLevelNum = - animationLevelNum < symbolNode.animationIndex ? symbolNode.animationIndex : animationLevelNum; - } - - if (animationLevelNum < 0) { - return false; - } - animationLevelNum = animationLevelNum + 1; - // unit animation : 1, multiple animation : 0 - int animationMode = animationLevelNum > 1 ? 0 : 1; - // get animation group paramaters - parameters = Drawing::HmSymbolConfigOhos::GetGroupParameters( - Drawing::DrawingAnimationType(symbolAnimationConfig->effectStrategy), uint16_t(animationLevelNum), - uint16_t(animationMode)); - if (parameters.empty()) { - return false; - } - return true; -} - +namespace SymbolAnimation { template bool CreateOrSetModifierValue(std::shared_ptr>& property, const T& value) { @@ -97,7 +44,7 @@ bool CreateOrSetModifierValue(std::shared_ptr>& property } template -bool ElementInMap(const std::string curElement, const std::map& curMap) +bool ElementInMap(const std::string& curElement, const std::map& curMap) { if (curMap.empty()) { return false; @@ -106,20 +53,44 @@ bool ElementInMap(const std::string curElement, const std::map& return (element != curMap.end()); } -template -bool ElementInMap(const std::string curElement, const std::map& curMap, T& value) +float CurveArgsInMap(const std::string& curElement, const std::map& curMap) { if (curMap.empty()) { - return false; + return 0.0; } auto element = curMap.find(curElement); if (element == curMap.end()) { - return false; + return 0.0; } - value = curMap.at(curElement); - return true; + return static_cast(element->second); } +void CreateAnimationTimingCurve(const OHOS::Rosen::Drawing::DrawingCurveType type, + const std::map& curveArgs, RSAnimationTimingCurve& curve) +{ + curve = RSAnimationTimingCurve(); + if (type == OHOS::Rosen::Drawing::DrawingCurveType::LINEAR) { + curve = RSAnimationTimingCurve::LINEAR; + } else if (type == OHOS::Rosen::Drawing::DrawingCurveType::SPRING) { + float scaleVelocity = CurveArgsInMap("velocity", curveArgs); + float scaleMass = CurveArgsInMap("mass", curveArgs); + float scaleStiffness = CurveArgsInMap("stiffness", curveArgs); + float scaleDamping = CurveArgsInMap("damping", curveArgs); + curve = RSAnimationTimingCurve::CreateInterpolatingSpring(scaleMass, scaleStiffness, scaleDamping, + scaleVelocity); + } else if (type == OHOS::Rosen::Drawing::DrawingCurveType::FRICTION || + type == OHOS::Rosen::Drawing::DrawingCurveType::SHARP) { + float ctrlX1 = CurveArgsInMap("ctrlX1", curveArgs); + float ctrlY1 = CurveArgsInMap("ctrlY1", curveArgs); + float ctrlX2 = CurveArgsInMap("ctrlX2", curveArgs); + float ctrlY2 = CurveArgsInMap("ctrlY2", curveArgs); + curve = RSAnimationTimingCurve::CreateCubicCurve(ctrlX1, ctrlY1, ctrlX2, ctrlY2); + } else { + return; + } +} +} // namespace SymbolAnimation + RSSymbolAnimation::RSSymbolAnimation() {} RSSymbolAnimation::~RSSymbolAnimation() {} @@ -140,7 +111,7 @@ bool RSSymbolAnimation::SetSymbolAnimation( return true; // pre code already clear nodes. } InitSupportAnimationTable(); - return ChooseAnimation(symbolAnimationConfig); + return SetPublicAnimation(symbolAnimationConfig); } void RSSymbolAnimation::InitSupportAnimationTable() @@ -149,20 +120,62 @@ void RSSymbolAnimation::InitSupportAnimationTable() publicSupportAnimations_ = { TextEngine::SymbolAnimationEffectStrategy::SYMBOL_BOUNCE, TextEngine::SymbolAnimationEffectStrategy::SYMBOL_APPEAR, TextEngine::SymbolAnimationEffectStrategy::SYMBOL_DISAPPEAR }; + upAndDownSupportAnimations_ = {TextEngine::SymbolAnimationEffectStrategy::SYMBOL_BOUNCE, + TextEngine::SymbolAnimationEffectStrategy::SYMBOL_SCALE}; } -bool RSSymbolAnimation::ChooseAnimation(const std::shared_ptr& symbolAnimationConfig) +bool RSSymbolAnimation::GetAnimationGroupParameters( + const std::shared_ptr& symbolAnimationConfig, + std::vector>& parameters) +{ + // count animation levels + int animationLevelNum = -1; + auto nodeNum = symbolAnimationConfig->numNodes; + for (uint32_t n = 0; n < nodeNum; n++) { + auto& symbolNode = symbolAnimationConfig->SymbolNodes[n]; + animationLevelNum = + animationLevelNum < symbolNode.animationIndex ? symbolNode.animationIndex : animationLevelNum; + } + + if (animationLevelNum < 0) { + return false; + } + animationLevelNum = animationLevelNum + 1; + // get animation group paramaters + if (std::count(upAndDownSupportAnimations_.begin(), upAndDownSupportAnimations_.end(), + symbolAnimationConfig->effectStrategy) != 0) { + parameters = Drawing::HmSymbolConfigOhos::GetGroupParameters( + Drawing::DrawingAnimationType(symbolAnimationConfig->effectStrategy), + static_cast(animationLevelNum), + symbolAnimationConfig->animationMode, symbolAnimationConfig->commonSubType); + } else { + parameters = Drawing::HmSymbolConfigOhos::GetGroupParameters( + Drawing::DrawingAnimationType(symbolAnimationConfig->effectStrategy), + static_cast(animationLevelNum), + symbolAnimationConfig->animationMode); + } + if (parameters.empty()) { + return false; + } + return true; +} + +bool RSSymbolAnimation::ChooseAnimation(const std::shared_ptr& rsNode, + std::vector& parameters, + const std::shared_ptr& symbolAnimationConfig) { if (std::count(publicSupportAnimations_.begin(), - publicSupportAnimations_.end(), symbolAnimationConfig->effectStrategy)) { - return SetPublicAnimation(symbolAnimationConfig); + publicSupportAnimations_.end(), symbolAnimationConfig->effectStrategy) != 0) { + SpliceAnimation(rsNode, parameters, symbolAnimationConfig->effectStrategy); } switch (symbolAnimationConfig->effectStrategy) { case TextEngine::SymbolAnimationEffectStrategy::SYMBOL_SCALE: - return SetScaleUnitAnimation(symbolAnimationConfig); + return SetScaleUnitAnimation(rsNode, parameters); case TextEngine::SymbolAnimationEffectStrategy::SYMBOL_VARIABLE_COLOR: - return SetVariableColorAnimation(symbolAnimationConfig); + return SetKeyframeAlphaAnimation(rsNode, parameters, symbolAnimationConfig); + case TextEngine::SymbolAnimationEffectStrategy::SYMBOL_PULSE: + return SetKeyframeAlphaAnimation(rsNode, parameters, symbolAnimationConfig); default: ROSEN_LOGD("[%{public}s] not support input animation type \n", __func__); return false; @@ -218,7 +231,7 @@ bool RSSymbolAnimation::SetPublicAnimation( ROSEN_LOGD("[%{public}s] invalid parameter \n", __func__); continue; } - SpliceAnimation(canvasNode, oneGroupParas, symbolAnimationConfig->effectStrategy); + ChooseAnimation(canvasNode, oneGroupParas, symbolAnimationConfig); } return true; } @@ -242,8 +255,9 @@ void RSSymbolAnimation::SetNodePivot(const std::shared_ptr& rsNode) { // Set Node Center Offset Vector2f curNodePivot = rsNode->GetStagingProperties().GetPivot(); - if (!IsEqual(curNodePivot, CENTER_NODE_COORDINATE)) { - bool isCreate = CreateOrSetModifierValue(pivotProperty_, CENTER_NODE_COORDINATE); + pivotProperty_ = nullptr; // reset + if (!(curNodePivot.x_ == CENTER_NODE_COORDINATE.x_ && curNodePivot.y_ == CENTER_NODE_COORDINATE.y_)) { + bool isCreate = SymbolAnimation::CreateOrSetModifierValue(pivotProperty_, CENTER_NODE_COORDINATE); if (isCreate) { auto pivotModifier = std::make_shared(pivotProperty_); rsNode->AddModifier(pivotModifier); @@ -269,7 +283,7 @@ void RSSymbolAnimation::BounceAnimation( const std::shared_ptr& rsNode, std::vector& parameters) { int animationStageNum = 2; // the count of atomizated animations - if (rsNode == nullptr && parameters.empty() && parameters.size() < animationStageNum) { + if (rsNode == nullptr || parameters.empty() || parameters.size() < animationStageNum) { ROSEN_LOGD("[%{public}s] : invalid input\n", __func__); return; } @@ -284,7 +298,7 @@ void RSSymbolAnimation::AppearAnimation( const std::shared_ptr& rsNode, std::vector& parameters) { int animationStageNum = 2; // the count of atomizated animations - if (rsNode == nullptr && parameters.empty() && parameters.size() < animationStageNum) { + if (rsNode == nullptr || parameters.empty() || parameters.size() < animationStageNum) { ROSEN_LOGD("[%{public}s] : invalid input\n", __func__); return; } @@ -295,7 +309,7 @@ void RSSymbolAnimation::AppearAnimation( GroupAnimationStart(rsNode, groupAnimation); } -Vector4f RSSymbolAnimation::CalculateOffset(const Drawing::Path& path, const float& offsetX, const float& offsetY) +Vector4f RSSymbolAnimation::CalculateOffset(const Drawing::Path& path, const float offsetX, const float offsetY) { auto rect = path.GetBounds(); float left = rect.GetLeft(); @@ -331,10 +345,9 @@ void RSSymbolAnimation::DrawSymbolOnCanvas( SetIconProperty(brush, pen, symbolNode); Drawing::Point offsetLocal = Drawing::Point { offsets[2], offsets[3] }; // index 2 offsetX 3 offsetY recordingCanvas->AttachBrush(brush); - recordingCanvas->DrawSymbol(symbolNode.symbolData, offsetLocal); - recordingCanvas->DetachBrush(); recordingCanvas->AttachPen(pen); recordingCanvas->DrawSymbol(symbolNode.symbolData, offsetLocal); + recordingCanvas->DetachBrush(); recordingCanvas->DetachPen(); } @@ -356,18 +369,11 @@ void RSSymbolAnimation::DrawPathOnCanvas( } bool RSSymbolAnimation::GetScaleUnitAnimationParas( - Drawing::DrawingPiecewiseParameter& scaleUnitParas, Vector2f& scaleValueBegin, Vector2f& scaleValue) + Drawing::DrawingPiecewiseParameter& scaleUnitParas, Vector2f& scaleValueBegin, Vector2f& scaleValueEnd) { - // AnimationType, Animation groups, animation_mode; animation_mode is 1 when Animation groups is 1 - auto scaleParas = Drawing::HmSymbolConfigOhos::GetGroupParameters(Drawing::SCALE_TYPE, 1, 1); - if (scaleParas.empty() || scaleParas[UNIT_GROUP].empty()) { - ROSEN_LOGD("[%{public}s] can not get scaleParas \n", __func__); - return false; - } - scaleUnitParas = scaleParas[UNIT_GROUP][UNIT_PERIOD]; - - auto scaleProperties = scaleUnitParas.properties; - if (!ElementInMap(SCALE_PROP_X, scaleProperties) || !ElementInMap(SCALE_PROP_Y, scaleProperties)) { + auto& scaleProperties = scaleUnitParas.properties; + if (!SymbolAnimation::ElementInMap(SCALE_PROP_X, scaleProperties) || + !SymbolAnimation::ElementInMap(SCALE_PROP_Y, scaleProperties)) { ROSEN_LOGD("[%{public}s] scaleProperties is null \n", __func__); return false; } @@ -378,52 +384,44 @@ bool RSSymbolAnimation::GetScaleUnitAnimationParas( } scaleValueBegin = { scaleProperties[SCALE_PROP_X][PROP_START], scaleProperties[SCALE_PROP_Y][PROP_START] }; - scaleValue = { scaleProperties[SCALE_PROP_X][PROP_END], scaleProperties[SCALE_PROP_Y][PROP_END] }; + scaleValueEnd = { scaleProperties[SCALE_PROP_X][PROP_END], scaleProperties[SCALE_PROP_Y][PROP_END] }; return true; } -bool RSSymbolAnimation::SetScaleUnitAnimation( - const std::shared_ptr& symbolAnimationConfig) +bool RSSymbolAnimation::SetScaleUnitAnimation(const std::shared_ptr& rsNode, + std::vector& parameters) { - if (rsNode_ == nullptr || symbolAnimationConfig == nullptr) { - ROSEN_LOGD("HmSymbol SetScaleUnitAnimation::getNode or get symbolAnimationConfig:failed"); + int validSize = 2; // 2 means this animation type has two animation stages + if (rsNode_ == nullptr || parameters.size() != validSize) { + ROSEN_LOGD("HmSymbol SetScaleUnitAnimation::getNode or get parameters:failed"); return false; } - auto nodeNum = symbolAnimationConfig->numNodes; - if (nodeNum == 0) { - return false; - } - auto symbolSpanId = symbolAnimationConfig->symbolSpanId; - auto canvasNode = RSCanvasNode::Create(); - if (rsNode_->canvasNodesListMap.count(symbolSpanId) > 0) { - rsNode_->canvasNodesListMap[symbolSpanId].emplace_back(canvasNode); - } else { - rsNode_->canvasNodesListMap[symbolSpanId] = { canvasNode }; - } - - auto& symbolNode = symbolAnimationConfig->SymbolNodes[UNIT_NODE]; - Vector4f offsets = CalculateOffset(symbolNode.symbolData.path_, symbolNode.nodeBoundary[0], - symbolNode.nodeBoundary[1]); // index 0 offsetX of layout, 1 offsetY of layout - if (!SetSymbolGeometry(canvasNode, Vector4f(offsets[0], offsets[1], // 0: offsetX of newNode; 1: offsetY - symbolNode.nodeBoundary[WIDTH], symbolNode.nodeBoundary[HEIGHT]))) { - return false; - } - Drawing::DrawingPiecewiseParameter scaleUnitParas; Vector2f scaleValueBegin; - Vector2f scaleValue; - if (!GetScaleUnitAnimationParas(scaleUnitParas, scaleValueBegin, scaleValue)) { + Vector2f scaleValueEnd; + // 0 means first stage of this animation + if (!GetScaleUnitAnimationParas(parameters[0], scaleValueBegin, scaleValueEnd)) { return false; } - Vector2f scaleValueEnd = scaleValueBegin; - auto animation = ScaleSymbolAnimation(canvasNode, scaleUnitParas, scaleValueBegin, scaleValue, scaleValueEnd); - if (animation == nullptr) { + scaleProperty_ = nullptr; // reset + bool isCreate = SymbolAnimation::CreateOrSetModifierValue(scaleProperty_, scaleValueBegin); + if (isCreate) { + auto scaleModifier = std::make_shared(scaleProperty_); + rsNode->AddModifier(scaleModifier); + } + auto animation0 = ScaleSymbolAnimation(rsNode, parameters[0], scaleValueEnd); + if (animation0 == nullptr) { return false; } - animation->Start(canvasNode); - auto recordingCanvas = canvasNode->BeginRecording(symbolNode.nodeBoundary[WIDTH], symbolNode.nodeBoundary[HEIGHT]); - DrawSymbolOnCanvas(recordingCanvas, symbolNode, offsets); - canvasNode->FinishRecording(); - rsNode_->AddChild(canvasNode, -1); + // 1 means second stage of this animation + if (!GetScaleUnitAnimationParas(parameters[1], scaleValueBegin, scaleValueEnd)) { + return false; + } + auto animation1 = ScaleSymbolAnimation(rsNode, parameters[1], scaleValueEnd); + if (animation1 == nullptr) { + return false; + } + animation0->Start(rsNode); + animation1->Start(rsNode); return true; } @@ -435,12 +433,12 @@ bool RSSymbolAnimation::SetSymbolGeometry(const std::shared_ptr& rsNode, std::shared_ptr> frameProperty = nullptr; std::shared_ptr> boundsProperty = nullptr; - bool isFrameCreate = CreateOrSetModifierValue(frameProperty, bounds); + bool isFrameCreate = SymbolAnimation::CreateOrSetModifierValue(frameProperty, bounds); if (isFrameCreate) { auto frameModifier = std::make_shared(frameProperty); rsNode->AddModifier(frameModifier); } - bool isBoundsCreate = CreateOrSetModifierValue(boundsProperty, bounds); + bool isBoundsCreate = SymbolAnimation::CreateOrSetModifierValue(boundsProperty, bounds); if (isBoundsCreate) { auto boundsModifier = std::make_shared(boundsProperty); rsNode->AddModifier(boundsModifier); @@ -451,149 +449,92 @@ bool RSSymbolAnimation::SetSymbolGeometry(const std::shared_ptr& rsNode, } std::shared_ptr RSSymbolAnimation::ScaleSymbolAnimation(const std::shared_ptr& rsNode, - const Drawing::DrawingPiecewiseParameter& scaleUnitParas, const Vector2f& scaleValueBegin, - const Vector2f& scaleValue, const Vector2f& scaleValueEnd) + const Drawing::DrawingPiecewiseParameter& scaleUnitParas, const Vector2f& scaleValueEnd) { if (rsNode == nullptr) { return nullptr; } - bool isCreate = CreateOrSetModifierValue(scaleStartProperty_, scaleValueBegin); - if (isCreate) { - auto scaleModifier = std::make_shared(scaleStartProperty_); - rsNode->AddModifier(scaleModifier); - } - CreateOrSetModifierValue(scaleProperty_, scaleValue); - CreateOrSetModifierValue(scaleEndProperty_, scaleValueEnd); - Vector2f curNodePivot = rsNode->GetStagingProperties().GetPivot(); - if (!IsEqual(curNodePivot, CENTER_NODE_COORDINATE)) { - isCreate = CreateOrSetModifierValue(pivotProperty_, CENTER_NODE_COORDINATE); - if (isCreate) { - auto pivotModifier = std::make_shared(pivotProperty_); - rsNode->AddModifier(pivotModifier); - } - } + SetNodePivot(rsNode); + RSAnimationTimingCurve scaleCurve; + SymbolAnimation::CreateAnimationTimingCurve(scaleUnitParas.curveType, scaleUnitParas.curveArgs, scaleCurve); - RSAnimationTimingCurve scaleCurve = SetScaleSpringTimingCurve(scaleUnitParas.curveArgs); + RSAnimationTimingProtocol protocol; + protocol.SetStartDelay(scaleUnitParas.delay); - auto keyframeAnimation = std::make_shared(scaleStartProperty_); - keyframeAnimation->SetStartDelay(scaleUnitParas.delay); - if (scaleUnitParas.duration != 0) { - keyframeAnimation->SetDuration(scaleUnitParas.duration); - } else { - keyframeAnimation->SetDuration(2000); // default duration is 2000ms + auto animations = RSNode::Animate(protocol, scaleCurve, [this, scaleValueEnd]() { + scaleProperty_->Set(scaleValueEnd); + }); + if (animations.size() <= 0) { + return nullptr; } - keyframeAnimation->AddKeyFrame(0.25f, scaleProperty_, scaleCurve); - keyframeAnimation->AddKeyFrame(0.75f, scaleProperty_, scaleCurve); - keyframeAnimation->AddKeyFrame(1.f, scaleEndProperty_, scaleCurve); - return keyframeAnimation; + return animations[0]; } -RSAnimationTimingCurve RSSymbolAnimation::SetScaleSpringTimingCurve(const std::map& curveArgs) -{ - double scaleVelocity = 0; - double scaleMass = 0; - double scaleStiffness = 0; - double scaleDamping = 0; - ElementInMap("velocity", curveArgs, scaleVelocity); - ElementInMap("mass", curveArgs, scaleMass); - ElementInMap("stiffness", curveArgs, scaleStiffness); - ElementInMap("damping", curveArgs, scaleDamping); - RSAnimationTimingCurve scaleCurve = RSAnimationTimingCurve::CreateSpringCurve(static_cast(scaleVelocity), - static_cast(scaleMass), static_cast(scaleStiffness), static_cast(scaleDamping)); - return scaleCurve; -} - -bool RSSymbolAnimation::SetVariableColorAnimation( +bool RSSymbolAnimation::SetKeyframeAlphaAnimation(const std::shared_ptr& rsNode, + std::vector& parameters, const std::shared_ptr& symbolAnimationConfig) { if (rsNode_ == nullptr || symbolAnimationConfig == nullptr) { ROSEN_LOGD("HmSymbol SetVariableColorAnimation::getNode or get symbolAnimationConfig:failed"); - return false; } - auto nodeNum = symbolAnimationConfig->numNodes; - if (nodeNum == 0) { + alphaPropertyStages_.clear(); + uint32_t duration = 0; + std::vector timePercents; + if (!GetKeyframeAlphaAnimationParas(parameters, duration, timePercents)) { return false; } - auto symbolSpanId = symbolAnimationConfig->symbolSpanId; - auto& symbolFirstNode = symbolAnimationConfig->SymbolNodes[0]; // calculate offset by the first node - Vector4f offsets = CalculateOffset(symbolFirstNode.symbolData.path_, symbolFirstNode.nodeBoundary[0], - symbolFirstNode.nodeBoundary[1]); // index 0 offsetX and 1 offsetY of layout - for (uint32_t n = 0; n < nodeNum; n++) { - auto& symbolNode = symbolAnimationConfig->SymbolNodes[n]; - auto canvasNode = RSCanvasNode::Create(); - if (rsNode_->canvasNodesListMap.count(symbolSpanId) > 0) { - rsNode_->canvasNodesListMap[symbolSpanId].emplace_back(canvasNode); - } else { - rsNode_->canvasNodesListMap[symbolSpanId] = { canvasNode }; - } - if (!SetSymbolGeometry(canvasNode, Vector4f(offsets[0], offsets[1], // 0: offsetX of newNode 1: offsetY - symbolNode.nodeBoundary[WIDTH], symbolNode.nodeBoundary[HEIGHT]))) { - return false; - } - auto recordingCanvas = - canvasNode->BeginRecording(symbolNode.nodeBoundary[WIDTH], symbolNode.nodeBoundary[HEIGHT]); - DrawPathOnCanvas(recordingCanvas, symbolNode, offsets); - canvasNode->FinishRecording(); - rsNode_->AddChild(canvasNode, -1); - - if (symbolNode.animationIndex == -1) { - continue; - } - std::shared_ptr animation = nullptr; - uint32_t duration = 0; - int delay = 0; - std::vector timePercents; - if (!GetVariableColorAnimationParas(symbolNode.animationIndex, duration, delay, timePercents)) { - return false; - } - auto alphaModifier = std::make_shared(alphaPropertyPhases_[0]); // initial the alpha status - canvasNode->AddModifier(alphaModifier); - animation = VariableColorSymbolAnimation(canvasNode, duration, delay, timePercents); - if (animation == nullptr) { - return false; - } - animation->Start(canvasNode); + // 0 means the first stage of a node + auto alphaModifier = std::make_shared(alphaPropertyStages_[0]); + rsNode->AddModifier(alphaModifier); + std::shared_ptr animation = nullptr; + animation = KeyframeAlphaSymbolAnimation(rsNode, parameters[0], duration, timePercents); + if (animation == nullptr) { + return false; } + + if (symbolAnimationConfig->effectStrategy == TextEngine::SymbolAnimationEffectStrategy::SYMBOL_VARIABLE_COLOR && + symbolAnimationConfig->animationMode == 0) { + animation->SetRepeatCount(1); + } else { + animation->SetRepeatCount(-1); // -1 means loop playback + } + animation->Start(rsNode); return true; } -bool RSSymbolAnimation::GetVariableColorAnimationParas( - const uint32_t index, uint32_t& totalDuration, int& delay, std::vector& timePercents) +bool RSSymbolAnimation::GetKeyframeAlphaAnimationParas( + std::vector& oneGroupParas, + uint32_t& totalDuration, std::vector& timePercents) { - // AnimationType, Animation groups, animation_mode; the variable color groups is 3 , animation_mode is 1 - auto multiGroupParas = Drawing::HmSymbolConfigOhos::GetGroupParameters(Drawing::VARIABLE_COLOR_TYPE, 3, 1); - if (multiGroupParas.size() <= index || multiGroupParas[index].empty()) { - ROSEN_LOGD("[%{public}s] can not get multiGroupParas \n", __func__); - return false; - } - auto oneGroupParas = multiGroupParas[index]; // index means the sequence number of node or animation layer if (oneGroupParas.empty()) { return false; } - delay = oneGroupParas[0].delay; // 0 means the first phase of a node totalDuration = 0; - // traverse all time phases + uint32_t interval = 0; + // traverse all time stages for (unsigned long i = 0; i < oneGroupParas.size(); i++) { - totalDuration = oneGroupParas[i].duration + totalDuration; - if (!ElementInMap(ALPHA_PROP, oneGroupParas[i].properties) || + if (i + 1 < oneGroupParas.size()) { + interval = oneGroupParas[i + 1].delay - + (static_cast(oneGroupParas[i].duration) + oneGroupParas[i].delay); + } else { + interval = 0; + } + totalDuration = oneGroupParas[i].duration + totalDuration + interval; + if (!SymbolAnimation::ElementInMap(ALPHA_PROP, oneGroupParas[i].properties) || oneGroupParas[i].properties[ALPHA_PROP].size() != PROPERTIES) { return false; } - // each node needs same alphaPropertyPhases - // desired result : alphaPropertyPhases_.size() = oneGroupParas.size() + 1 - if (alphaPropertyPhases_.size() <= oneGroupParas.size()) { - if (i == 0) { - float alphaValue = oneGroupParas[i].properties.at(ALPHA_PROP)[PROP_START]; // the first value - std::shared_ptr> alphaPropertyPhase = nullptr; - CreateOrSetModifierValue(alphaPropertyPhase, alphaValue); - alphaPropertyPhases_.push_back(alphaPropertyPhase); - } - float alphaValue = oneGroupParas[i].properties.at(ALPHA_PROP)[PROP_END]; // the value of the key frame needs - std::shared_ptr> alphaPropertyPhase = nullptr; - CreateOrSetModifierValue(alphaPropertyPhase, alphaValue); - alphaPropertyPhases_.push_back(alphaPropertyPhase); - } + // the value of the key frame needs + float alphaValueStart = oneGroupParas[i].properties[ALPHA_PROP][PROP_START]; + std::shared_ptr> alphaPropertyStart = nullptr; + SymbolAnimation::CreateOrSetModifierValue(alphaPropertyStart, alphaValueStart); + alphaPropertyStages_.push_back(alphaPropertyStart); + + float alphaValueEnd = oneGroupParas[i].properties[ALPHA_PROP][PROP_END]; + std::shared_ptr> alphaPropertyEnd = nullptr; + SymbolAnimation::CreateOrSetModifierValue(alphaPropertyEnd, alphaValueEnd); + alphaPropertyStages_.push_back(alphaPropertyEnd); } return CalcTimePercents(timePercents, static_cast(totalDuration), oneGroupParas); } @@ -606,11 +547,21 @@ bool RSSymbolAnimation::CalcTimePercents(std::vector& timePercents, const } uint32_t duration = 0; float timePercent = 0; + uint32_t interval = 0; timePercents.push_back(timePercent); // the first property of timePercent for (unsigned long i = 0; i < oneGroupParas.size(); i++) { - timePercent = static_cast(oneGroupParas[i].duration + duration) / static_cast(totalDuration); - timePercents.push_back(timePercent); duration = duration + oneGroupParas[i].duration; + timePercent = static_cast(duration) / static_cast(totalDuration); + timePercent = timePercent > 1 ? 1.0 : timePercent; + timePercents.push_back(timePercent); + if (i + 1 < oneGroupParas.size()) { + interval = oneGroupParas[i + 1].delay - + (static_cast(oneGroupParas[i].duration) + oneGroupParas[i].delay); + duration = duration + interval; + timePercent = static_cast(duration) / static_cast(totalDuration); + timePercent = timePercent > 1 ? 1.0 : timePercent; + timePercents.push_back(timePercent); + } } return true; } @@ -627,21 +578,24 @@ void RSSymbolAnimation::SetIconProperty(Drawing::Brush& brush, Drawing::Pen& pen return; } -std::shared_ptr RSSymbolAnimation::VariableColorSymbolAnimation(const std::shared_ptr& rsNode, - const uint32_t& duration, const int& delay, const std::vector& timePercents) +std::shared_ptr RSSymbolAnimation::KeyframeAlphaSymbolAnimation(const std::shared_ptr& rsNode, + const Drawing::DrawingPiecewiseParameter& oneStageParas, const uint32_t duration, + const std::vector& timePercents) { - if (alphaPropertyPhases_.size() == 0 || timePercents.size() != alphaPropertyPhases_.size()) { + if (alphaPropertyStages_.size() == 0 || timePercents.size() != alphaPropertyStages_.size()) { return nullptr; } - auto keyframeAnimation = std::make_shared(alphaPropertyPhases_[0]); // initial the alpha status + auto keyframeAnimation = std::make_shared(alphaPropertyStages_[0]); // initial the alpha status if (keyframeAnimation == nullptr || rsNode == nullptr) { return nullptr; } - keyframeAnimation->SetStartDelay(delay); + keyframeAnimation->SetStartDelay(oneStageParas.delay); keyframeAnimation->SetDuration(duration); + RSAnimationTimingCurve timingCurve; + SymbolAnimation::CreateAnimationTimingCurve(oneStageParas.curveType, oneStageParas.curveArgs, timingCurve); std::vector, RSAnimationTimingCurve>> keyframes; - for (unsigned long i = 1; i < alphaPropertyPhases_.size(); i++) { - keyframes.push_back(std::make_tuple(timePercents[i], alphaPropertyPhases_[i], RSAnimationTimingCurve::LINEAR)); + for (unsigned long i = 1; i < alphaPropertyStages_.size(); i++) { + keyframes.push_back(std::make_tuple(timePercents[i], alphaPropertyStages_[i], timingCurve)); } keyframeAnimation->AddKeyFrames(keyframes); return keyframeAnimation; @@ -669,7 +623,7 @@ void RSSymbolAnimation::ScaleAnimationBase(const std::shared_ptr& rsNode const Vector2f scaleValueEnd = { scaleParameter.properties["sx"][1], scaleParameter.properties["sy"][1] }; std::shared_ptr> scaleProperty; - bool isCreate = CreateOrSetModifierValue(scaleProperty, scaleValueBegin); + bool isCreate = SymbolAnimation::CreateOrSetModifierValue(scaleProperty, scaleValueBegin); if (!isCreate) { ROSEN_LOGD("[%{public}s] : invalid parameter \n", __func__); return; @@ -681,7 +635,7 @@ void RSSymbolAnimation::ScaleAnimationBase(const std::shared_ptr& rsNode // set animation curve and protocol RSAnimationTimingCurve scaleCurve; - CreateAnimationTimingCurve(scaleParameter.curveType, scaleParameter.curveArgs, scaleCurve); + SymbolAnimation::CreateAnimationTimingCurve(scaleParameter.curveType, scaleParameter.curveArgs, scaleCurve); RSAnimationTimingProtocol scaleprotocol; int startDelay = int(scaleParameter.delay); @@ -717,7 +671,7 @@ void RSSymbolAnimation::AlphaAnimationBase(const std::shared_ptr& rsNode std::shared_ptr> alphaProperty; - if (!CreateOrSetModifierValue(alphaProperty, alphaBegin)) { + if (!SymbolAnimation::CreateOrSetModifierValue(alphaProperty, alphaBegin)) { return; } auto alphaModifier = std::make_shared(alphaProperty); @@ -728,7 +682,7 @@ void RSSymbolAnimation::AlphaAnimationBase(const std::shared_ptr& rsNode alphaProtocol.SetStartDelay(alphaParameter.delay); alphaProtocol.SetDuration(alphaParameter.duration); RSAnimationTimingCurve alphaCurve; - CreateAnimationTimingCurve(alphaParameter.curveType, alphaParameter.curveArgs, alphaCurve); + SymbolAnimation::CreateAnimationTimingCurve(alphaParameter.curveType, alphaParameter.curveArgs, alphaCurve); std::vector> animations1 = RSNode::Animate( alphaProtocol, alphaCurve, [&alphaProperty, &alphaValueEnd]() { alphaProperty->Set(alphaValueEnd); }); diff --git a/rosen/modules/render_service_client/core/animation/rs_symbol_animation.h b/rosen/modules/render_service_client/core/animation/rs_symbol_animation.h index b640a33538..f70f74867d 100644 --- a/rosen/modules/render_service_client/core/animation/rs_symbol_animation.h +++ b/rosen/modules/render_service_client/core/animation/rs_symbol_animation.h @@ -45,14 +45,21 @@ public: // set symbol animation manager bool SetSymbolAnimation(const std::shared_ptr& symbolAnimationConfig); - bool SetScaleUnitAnimation(const std::shared_ptr& symbolAnimationConfig); - bool SetVariableColorAnimation(const std::shared_ptr& symbolAnimationConfig); private: // SetPublicAnimation is interface for animation that can be spliced by atomizated animations bool SetPublicAnimation(const std::shared_ptr& symbolAnimationConfig); + bool GetAnimationGroupParameters(const std::shared_ptr& symbolAnimationConfig, + std::vector>& parameters); // choose the animation is a public animation or special animation - bool ChooseAnimation(const std::shared_ptr& symbolAnimationConfig); + bool ChooseAnimation(const std::shared_ptr& rsNode, + std::vector& parameters, + const std::shared_ptr& symbolAnimationConfig); + bool SetKeyframeAlphaAnimation(const std::shared_ptr& rsNode, + std::vector& parameters, + const std::shared_ptr& symbolAnimationConfig); + bool SetScaleUnitAnimation(const std::shared_ptr& rsNode, + std::vector& parameters); void InitSupportAnimationTable(); @@ -85,7 +92,7 @@ private: void SetIconProperty(Drawing::Brush& brush, Drawing::Pen& pen, TextEngine::SymbolNode& symbolNode); - Vector4f CalculateOffset(const Drawing::Path& path, const float& offsetX, const float& offsetY); + Vector4f CalculateOffset(const Drawing::Path& path, const float offsetX, const float offsetY); void DrawSymbolOnCanvas( ExtendRecordingCanvas* recordingCanvas, TextEngine::SymbolNode& symbolNode, const Vector4f& offsets); void DrawPathOnCanvas( @@ -95,29 +102,29 @@ private: std::shared_ptr ScaleSymbolAnimation(const std::shared_ptr& rsNode, const Drawing::DrawingPiecewiseParameter& scaleUnitParas, - const Vector2f& scaleValueBegin = Vector2f { 0.f, 0.f }, const Vector2f& scaleValue = Vector2f { 0.f, 0.f }, const Vector2f& scaleValueEnd = Vector2f { 0.f, 0.f }); bool GetScaleUnitAnimationParas( - Drawing::DrawingPiecewiseParameter& scaleUnitParas, Vector2f& scaleValueBegin, Vector2f& scaleValue); - RSAnimationTimingCurve SetScaleSpringTimingCurve(const std::map& curveArgs); + Drawing::DrawingPiecewiseParameter& scaleUnitParas, Vector2f& scaleValueBegin, Vector2f& scaleValueEnd); - std::shared_ptr VariableColorSymbolAnimation(const std::shared_ptr& rsNode, - const uint32_t& duration, const int& delay, const std::vector& timePercents); - bool GetVariableColorAnimationParas( - const uint32_t index, uint32_t& totalDuration, int& delay, std::vector& timePercents); + std::shared_ptr KeyframeAlphaSymbolAnimation(const std::shared_ptr& rsNode, + const Drawing::DrawingPiecewiseParameter& oneStageParas, + const uint32_t duration, const std::vector& timePercents); + bool GetKeyframeAlphaAnimationParas(std::vector& oneGroupParas, + uint32_t& totalDuration, std::vector& timePercents); std::shared_ptr rsNode_ = nullptr; // scale symbol animation - std::shared_ptr> scaleStartProperty_ = nullptr; std::shared_ptr> scaleProperty_ = nullptr; - std::shared_ptr> scaleEndProperty_ = nullptr; std::shared_ptr> pivotProperty_ = nullptr; // variableColor symbol animation - std::vector>> alphaPropertyPhases_; + std::vector>> alphaPropertyStages_; + // animation support splice base animation std::vector publicSupportAnimations_ = {}; + // animation support up&down interface + std::vector upAndDownSupportAnimations_ = {}; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_client/core/modifier/rs_property.cpp b/rosen/modules/render_service_client/core/modifier/rs_property.cpp index 6395c3e25c..88181b9bed 100644 --- a/rosen/modules/render_service_client/core/modifier/rs_property.cpp +++ b/rosen/modules/render_service_client/core/modifier/rs_property.cpp @@ -247,6 +247,12 @@ void RSProperty>::UpdateToRender( UPDATE_TO_RENDER(RSUpdatePropertyEmitterUpdater, value, type); } template<> +void RSProperty>::UpdateToRender( + const std::shared_ptr& value, PropertyUpdateType type) const +{ + UPDATE_TO_RENDER(RSUpdatePropertyParticleNoiseField, value, type); +} +template<> void RSProperty>::UpdateToRender( const std::shared_ptr& value, PropertyUpdateType type) const { diff --git a/rosen/modules/render_service_client/core/modifier/rs_property.h b/rosen/modules/render_service_client/core/modifier/rs_property.h index 04dd4a25f5..e400daf06e 100644 --- a/rosen/modules/render_service_client/core/modifier/rs_property.h +++ b/rosen/modules/render_service_client/core/modifier/rs_property.h @@ -711,6 +711,9 @@ template<> RSC_EXPORT void RSProperty>::UpdateToRender( const std::shared_ptr& value, PropertyUpdateType type) const; template<> +RSC_EXPORT void RSProperty>::UpdateToRender( + const std::shared_ptr& value, PropertyUpdateType type) const; +template<> RSC_EXPORT void RSProperty>::UpdateToRender( const std::shared_ptr& value, PropertyUpdateType type) const; template<> diff --git a/rosen/modules/render_service_client/core/modifier/rs_property_modifier.h b/rosen/modules/render_service_client/core/modifier/rs_property_modifier.h index 5198789e61..2e1509e3ea 100755 --- a/rosen/modules/render_service_client/core/modifier/rs_property_modifier.h +++ b/rosen/modules/render_service_client/core/modifier/rs_property_modifier.h @@ -562,6 +562,15 @@ protected: std::shared_ptr CreateRenderModifier() const override; }; +class RSC_EXPORT RSParticleNoiseFieldModifier : public RSForegroundModifier { +public: + explicit RSParticleNoiseFieldModifier(const std::shared_ptr& property); + virtual ~RSParticleNoiseFieldModifier() = default; +protected: + RSModifierType GetModifierType() const override; + std::shared_ptr CreateRenderModifier() const override; +}; + class RSC_EXPORT RSDynamicDimDegreeModifier : public RSForegroundModifier { public: explicit RSDynamicDimDegreeModifier(const std::shared_ptr& property); diff --git a/rosen/modules/render_service_client/core/transaction/rs_interfaces.cpp b/rosen/modules/render_service_client/core/transaction/rs_interfaces.cpp index da12cb779a..ecc3a78978 100644 --- a/rosen/modules/render_service_client/core/transaction/rs_interfaces.cpp +++ b/rosen/modules/render_service_client/core/transaction/rs_interfaces.cpp @@ -345,6 +345,11 @@ std::shared_ptr RSInterfaces::CreateVSyncReceiver( return renderServiceClient_->CreateVSyncReceiver(name, looper, id, windowNodeId); } +std::shared_ptr RSInterfaces::CreatePixelMapFromSurfaceId(uint64_t surfaceId, const Rect &srcRect) +{ + return renderServiceClient_->CreatePixelMapFromSurfaceId(surfaceId, srcRect); +} + int32_t RSInterfaces::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) { return renderServiceClient_->GetScreenHDRCapability(id, screenHdrCapability); diff --git a/rosen/modules/render_service_client/core/transaction/rs_interfaces.h b/rosen/modules/render_service_client/core/transaction/rs_interfaces.h index 4b5e517d30..1e6a29eb2e 100644 --- a/rosen/modules/render_service_client/core/transaction/rs_interfaces.h +++ b/rosen/modules/render_service_client/core/transaction/rs_interfaces.h @@ -186,6 +186,8 @@ public: const std::shared_ptr &looper = nullptr, NodeId windowNodeId = 0); + std::shared_ptr CreatePixelMapFromSurfaceId(uint64_t surfaceId, const Rect &srcRect); + int32_t RegisterOcclusionChangeCallback(const OcclusionChangeCallback& callback); int32_t RegisterSurfaceOcclusionChangeCallback( @@ -227,7 +229,7 @@ public: void ReportEventJankFrame(DataBaseRs info); void ReportGameStateData(GameStateData info); - + void EnableCacheForRotation(); void DisableCacheForRotation(); diff --git a/rosen/modules/render_service_client/core/ui/rs_node.cpp b/rosen/modules/render_service_client/core/ui/rs_node.cpp index fefb3fedf0..69677ab9dd 100755 --- a/rosen/modules/render_service_client/core/ui/rs_node.cpp +++ b/rosen/modules/render_service_client/core/ui/rs_node.cpp @@ -1056,6 +1056,13 @@ void RSNode::SetEmitterUpdater(const std::shared_ptr& para) RSModifierType::PARTICLE_EMITTER_UPDATER, para); } +// Set Particle Noise Field +void RSNode::SetParticleNoiseField(const std::shared_ptr& para) +{ + SetProperty>>( + RSModifierType::PARTICLE_NOISE_FIELD, para); +} + // foreground void RSNode::SetForegroundColor(uint32_t colorValue) { diff --git a/rosen/modules/render_service_client/core/ui/rs_node.h b/rosen/modules/render_service_client/core/ui/rs_node.h index bdb5ea552a..83bf0d6077 100755 --- a/rosen/modules/render_service_client/core/ui/rs_node.h +++ b/rosen/modules/render_service_client/core/ui/rs_node.h @@ -237,6 +237,7 @@ public: void SetParticleParams( std::vector& particleParams, const std::function& finishCallback = nullptr); void SetEmitterUpdater(const std::shared_ptr& para); + void SetParticleNoiseField(const std::shared_ptr& para); void SetForegroundColor(uint32_t colorValue); void SetBackgroundColor(uint32_t colorValue); void SetBackgroundShader(const std::shared_ptr& shader); diff --git a/rosen/modules/texgine/BUILD.gn b/rosen/modules/texgine/BUILD.gn index 54cdd53042..15eefffe48 100644 --- a/rosen/modules/texgine/BUILD.gn +++ b/rosen/modules/texgine/BUILD.gn @@ -102,6 +102,7 @@ ohos_source_set("libtexgine_source") { configs = [ ":libtexgine_config", "//build/config/compiler:exceptions", + "//build/config/compiler:rtti", ] public_configs = [ ":libtexgine_public_config" ] diff --git a/rosen/test/2d_engine/unittest/rosen_text/hm_symbol/hm_symbol_txt_test.cpp b/rosen/test/2d_engine/unittest/rosen_text/hm_symbol/hm_symbol_txt_test.cpp index 1e27260436..7bc1446e82 100644 --- a/rosen/test/2d_engine/unittest/rosen_text/hm_symbol/hm_symbol_txt_test.cpp +++ b/rosen/test/2d_engine/unittest/rosen_text/hm_symbol/hm_symbol_txt_test.cpp @@ -168,7 +168,7 @@ HWTEST_F(OHHmSymbolTxtTest, OHHmSymbolTxtTest007, TestSize.Level1) /* * @tc.name: OHHmSymbolTxtTest - * @tc.desc: test for symbol SetAminationStart + * @tc.desc: test for symbol SetAnimationStart * @tc.type: FUNC */ HWTEST_F(OHHmSymbolTxtTest, OHHmSymbolTxtTest008, TestSize.Level1) @@ -176,9 +176,9 @@ HWTEST_F(OHHmSymbolTxtTest, OHHmSymbolTxtTest008, TestSize.Level1) TextStyle style; style.isSymbolGlyph = true; SPText::TextStyle textStyle; - style.symbol.SetAminationStart(true); + style.symbol.SetAnimationStart(true); textStyle = AdapterTxt::Convert(style); - EXPECT_EQ(textStyle.symbol.GetAminationStart(), true); + EXPECT_EQ(textStyle.symbol.GetAnimationStart(), true); } /* diff --git a/rosen/test/2d_graphics/unittest/effect/image_filter_test.cpp b/rosen/test/2d_graphics/unittest/effect/image_filter_test.cpp index 8705ff9e36..e4e25ee2b0 100644 --- a/rosen/test/2d_graphics/unittest/effect/image_filter_test.cpp +++ b/rosen/test/2d_graphics/unittest/effect/image_filter_test.cpp @@ -285,6 +285,20 @@ HWTEST_F(ImageFilterTest, CreateShaderImageFilterTest002, TestSize.Level1) auto imageFilter = ImageFilter::CreateShaderImageFilter(nullptr); EXPECT_TRUE(imageFilter != nullptr); } + +/* + * @tc.name: CreateShaderImageFilterTest003 + * @tc.desc: test for creating a filter that with invalid input. + * @tc.type: FUNC + * @tc.require: I77M3W + */ +HWTEST_F(ImageFilterTest, CreateShaderImageFilterTest003, TestSize.Level1) +{ + std::shared_ptr effect = ShaderEffect::CreateColorShader(0); + Rect rect {0, 0, 100.0f, 100.0f}; + auto imageFilter = ImageFilter::CreateShaderImageFilter(effect, rect); + EXPECT_TRUE(imageFilter != nullptr); +} } // namespace Drawing } // namespace Rosen } // namespace OHOS diff --git a/rosen/test/2d_graphics/unittest/ndk/drawing_text_typography_test.cpp b/rosen/test/2d_graphics/unittest/ndk/drawing_text_typography_test.cpp index 986a4b1c68..cd7c683315 100644 --- a/rosen/test/2d_graphics/unittest/ndk/drawing_text_typography_test.cpp +++ b/rosen/test/2d_graphics/unittest/ndk/drawing_text_typography_test.cpp @@ -2350,4 +2350,82 @@ HWTEST_F(OH_Drawing_TypographyTest, OH_Drawing_TypographyTest083, TestSize.Level OH_Drawing_DestroyTextStyle(txtStyle); OH_Drawing_DestroyTextStyle(txtStyleCompare); } + +/* + * @tc.name: OH_Drawing_TypographyTest084 + * @tc.desc: test for BREAK_STRATEGY_GREEDY + * @tc.type: FUNC + */ +HWTEST_F(OH_Drawing_TypographyTest, OH_Drawing_TypographyTest084, TestSize.Level1) +{ + OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle(); + OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle(); + OH_Drawing_SetTypographyTextBreakStrategy(typoStyle, BREAK_STRATEGY_GREEDY); + OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, + OH_Drawing_CreateFontCollection()); + EXPECT_TRUE(handler != nullptr); + OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle); + const char* text = "breakStrategyTest breakStrategy breakStrategyGreedyTest"; + OH_Drawing_TypographyHandlerAddText(handler, text); + OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler); + // {1.2, 3.4} for unit test + const float indents[] = {1.2, 3.4}; + OH_Drawing_TypographySetIndents(typography, 2, indents); + // 300.0 for unit test + double maxWidth = 300.0; + OH_Drawing_TypographyLayout(typography, maxWidth); + EXPECT_EQ(maxWidth, OH_Drawing_TypographyGetMaxWidth(typography)); +} + +/* + * @tc.name: OH_Drawing_TypographyTest085 + * @tc.desc: test for BREAK_STRATEGY_BALANCED + * @tc.type: FUNC + */ +HWTEST_F(OH_Drawing_TypographyTest, OH_Drawing_TypographyTest085, TestSize.Level1) +{ + OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle(); + OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle(); + OH_Drawing_SetTypographyTextBreakStrategy(typoStyle, BREAK_STRATEGY_BALANCED); + OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, + OH_Drawing_CreateFontCollection()); + EXPECT_TRUE(handler != nullptr); + OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle); + const char* text = "breakStrategyTest breakStrategy breakStrategyBALANCEDTest"; + OH_Drawing_TypographyHandlerAddText(handler, text); + OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler); + // {1.2, 3.4} for unit test + const float indents[] = {1.2, 3.4}; + OH_Drawing_TypographySetIndents(typography, 2, indents); + // 300.0 for unit test + double maxWidth = 300.0; + OH_Drawing_TypographyLayout(typography, maxWidth); + EXPECT_EQ(maxWidth, OH_Drawing_TypographyGetMaxWidth(typography)); +} + +/* + * @tc.name: OH_Drawing_TypographyTest086 + * @tc.desc: test for BREAK_STRATEGY_HIGH_QUALITY + * @tc.type: FUNC + */ +HWTEST_F(OH_Drawing_TypographyTest, OH_Drawing_TypographyTest086, TestSize.Level1) +{ + OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle(); + OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle(); + OH_Drawing_SetTypographyTextBreakStrategy(typoStyle, BREAK_STRATEGY_HIGH_QUALITY); + OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, + OH_Drawing_CreateFontCollection()); + EXPECT_TRUE(handler != nullptr); + OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle); + const char* text = "breakStrategyTest breakStrategy breakStrategyHighQualityTest"; + OH_Drawing_TypographyHandlerAddText(handler, text); + OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler); + // {1.2, 3.4} for unit test + const float indents[] = {1.2, 3.4}; + OH_Drawing_TypographySetIndents(typography, 2, indents); + // 300.0 for unit test + double maxWidth = 300.0; + OH_Drawing_TypographyLayout(typography, maxWidth); + EXPECT_EQ(maxWidth, OH_Drawing_TypographyGetMaxWidth(typography)); +} } \ No newline at end of file diff --git a/rosen/test/frame_analyzer/unittest/BUILD.gn b/rosen/test/frame_analyzer/unittest/BUILD.gn index f0cf769feb..4e29301b0f 100644 --- a/rosen/test/frame_analyzer/unittest/BUILD.gn +++ b/rosen/test/frame_analyzer/unittest/BUILD.gn @@ -13,10 +13,13 @@ import("//build/test.gni") import("//foundation/arkui/ace_engine/ace_config.gni") +import("//foundation/graphic/graphic_2d/graphic_config.gni") ohos_unittest("frame_analyzer_test") { module_out_path = "graphic_2d/rosen/modules/frame_analyzer" + include_dirs = [ "$graphic_2d_root/rosen/modules/frame_analyzer/src" ] + sources = [ "frame_collector_test.cpp", "frame_painter_test.cpp", diff --git a/rosen/test/frame_analyzer/unittest/frame_saver_test.cpp b/rosen/test/frame_analyzer/unittest/frame_saver_test.cpp index c45832cc21..e72015f443 100644 --- a/rosen/test/frame_analyzer/unittest/frame_saver_test.cpp +++ b/rosen/test/frame_analyzer/unittest/frame_saver_test.cpp @@ -16,7 +16,7 @@ #include #include -#include "../src/frame_saver.h" +#include "frame_saver.h" #include "frame_collector.h" #include "frame_painter.h" using namespace testing; diff --git a/rosen/test/render_service/render_service/unittest/pipeline/mock/mock_hdi_device.h b/rosen/test/render_service/render_service/unittest/pipeline/mock/mock_hdi_device.h index b5885cf353..5f3ec3d7ad 100644 --- a/rosen/test/render_service/render_service/unittest/pipeline/mock/mock_hdi_device.h +++ b/rosen/test/render_service/render_service/unittest/pipeline/mock/mock_hdi_device.h @@ -90,7 +90,8 @@ public: MOCK_METHOD4(CreateLayer, int32_t(uint32_t, const GraphicLayerInfo&, uint32_t, uint32_t&)); MOCK_METHOD2(CloseLayer, int32_t(uint32_t, uint32_t)); - MOCK_METHOD4(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&)); + MOCK_METHOD6(CommitAndGetReleaseFence, int32_t(uint32_t, sptr&, int32_t&, bool&, + std::vector&, std::vector>&)); MOCK_METHOD0(Destroy, void()); static GraphicDispPowerStatus powerStatusMock_; diff --git a/rosen/test/render_service/render_service/unittest/screen_manager/BUILD.gn b/rosen/test/render_service/render_service/unittest/screen_manager/BUILD.gn index a5c77fa21d..da9b763b80 100644 --- a/rosen/test/render_service/render_service/unittest/screen_manager/BUILD.gn +++ b/rosen/test/render_service/render_service/unittest/screen_manager/BUILD.gn @@ -13,6 +13,7 @@ import("//build/test.gni") import("//foundation/arkui/ace_engine/ace_config.gni") +import("//foundation/graphic/graphic_2d/graphic_config.gni") module_output_path = "graphic/rosen_engine/render_service/screen_manager" @@ -38,6 +39,7 @@ ohos_unittest("RSScreenManagerTest") { "//foundation/graphic/graphic_2d/rosen/include", "//foundation/graphic/graphic_2d/rosen/test/include", "//foundation/barrierfree/accessibility/interfaces/innerkits/acfwk/include", + "$graphic_2d_root/rosen/test/render_service/render_service/unittest/pipeline/mock", ] deps = [ @@ -90,6 +92,7 @@ ohos_unittest("RSScreenTest") { "//foundation/graphic/graphic_2d/rosen/include", "//foundation/graphic/graphic_2d/rosen/test/include", "//foundation/barrierfree/accessibility/interfaces/innerkits/acfwk/include", + "$graphic_2d_root/rosen/test/render_service/render_service/unittest/pipeline/mock", ] deps = [ diff --git a/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_manager_test.cpp b/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_manager_test.cpp index fd8b2e529f..902b9c8160 100644 --- a/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_manager_test.cpp +++ b/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_manager_test.cpp @@ -17,7 +17,7 @@ #include "limit_number.h" #include "screen_manager/rs_screen_manager.h" #include "transaction/rs_interfaces.h" -#include "../pipeline/mock/mock_hdi_device.h" +#include "mock_hdi_device.h" using namespace testing; using namespace testing::ext; diff --git a/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_test.cpp b/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_test.cpp index fb62e78402..e0f819e866 100644 --- a/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_test.cpp +++ b/rosen/test/render_service/render_service/unittest/screen_manager/rs_screen_test.cpp @@ -16,7 +16,7 @@ #include "gtest/gtest.h" #include "limit_number.h" #include "screen_manager/rs_screen.h" -#include "../pipeline/mock/mock_hdi_device.h" +#include "mock_hdi_device.h" using namespace testing; using namespace testing::ext;