mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-27 09:10:54 +00:00
Merge branch 'master' of gitee.com:openharmony/graphic_graphic_2d into FixedTheFormatOfCode
Signed-off-by: changleipeng <changleipeng4@huawei.com>
This commit is contained in:
commit
769ebf1754
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
}
|
||||
|
@ -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<std::mutex> locker(mtx_);
|
||||
RNVFlag_ = RNVFlag;
|
||||
}
|
||||
bool GetRNVFlag()
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<IVSyncConnection> connection_;
|
||||
|
@ -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 {
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "wm_common.h"
|
||||
|
||||
#include "../common/graphic_common.h"
|
||||
#include "common/graphic_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace OHOS {
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
#include "../common/graphic_common.h"
|
||||
#include "common/graphic_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace OHOS {
|
||||
|
@ -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") {
|
||||
|
@ -14,19 +14,23 @@
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#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<Global::Resource::ResourceManager> 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<Global::Resource::ResourceManager>(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<char[]> indexStr = std::make_unique<char[]>(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<char[]> bundleNameStr = std::make_unique<char[]>(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<char[]> moduleNameStr = std::make_unique<char[]>(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<int32_t>(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<int32_t>(ResourceType::RAWFILE)) {
|
||||
size_t dataLen = 0;
|
||||
std::unique_ptr<uint8_t[]> 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
|
||||
|
@ -18,8 +18,10 @@
|
||||
|
||||
#include <native_engine/native_engine.h>
|
||||
#include <native_engine/native_value.h>
|
||||
#include "resource_manager.h"
|
||||
#include "font_collection.h"
|
||||
#include "js_text_utils.h"
|
||||
#include <memory>
|
||||
|
||||
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<Global::Resource::ResourceManager> 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<FontCollection> m_fontCollection = nullptr;
|
||||
|
@ -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
|
||||
|
@ -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<std::string> 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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@ SPText::ParagraphStyle Convert(const TypographyStyle& style)
|
||||
.customSpTextStyle = style.customTextStyle,
|
||||
.textHeightBehavior = static_cast<SPText::TextHeightBehavior>(style.textHeightBehavior),
|
||||
.hintingIsOn = style.hintingIsOn,
|
||||
.breakStrategy = static_cast<SPText::BreakStrategy>(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);
|
||||
|
@ -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<std::string, int> visualMap_;
|
||||
Drawing::DrawingCommonSubType commonSubType_ = Drawing::DrawingCommonSubType::UP;
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ skt::ParagraphStyle ParagraphBuilderImpl::TextStyleToSkStyle(const ParagraphStyl
|
||||
strutStyle.setForceStrutHeight(txt.forceStrutHeight);
|
||||
strutStyle.setStrutEnabled(txt.strutEnabled);
|
||||
strutStyle.setWordBreakType(static_cast<skt::WordBreakType>(txt.wordBreakType));
|
||||
strutStyle.setLineBreakStrategy(static_cast<skt::LineBreakStrategy>(txt.breakStrategy));
|
||||
skStyle.setStrutStyle(strutStyle);
|
||||
|
||||
skStyle.setTextAlign(static_cast<skt::TextAlign>(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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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<bool(const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig>&)>
|
||||
|
@ -127,7 +127,7 @@ void HMSymbolRun::DrawSymbol(RSCanvas* canvas, RSTextBlob* blob, const RSPoint&
|
||||
RSEffectStrategy symbolEffect = symbolTxt.GetEffectStrategy();
|
||||
uint32_t symbolId = static_cast<uint32_t>(glyphId);
|
||||
std::pair<double, double> 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;
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<ImageFilter> CreateShaderImageFilter(std::shared_ptr<ShaderEffect> shader);
|
||||
static std::shared_ptr<ImageFilter> CreateShaderImageFilter(std::shared_ptr<ShaderEffect> shader,
|
||||
const Rect& rect = {
|
||||
-std::numeric_limits<scalar>::infinity(), -std::numeric_limits<scalar>::infinity(),
|
||||
std::numeric_limits<scalar>::infinity(), std::numeric_limits<scalar>::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<ImageFilter> background,
|
||||
std::shared_ptr<ImageFilter> foreground = nullptr) noexcept;
|
||||
ImageFilter(FilterType t, std::shared_ptr<ShaderEffect> shader) noexcept;
|
||||
ImageFilter(FilterType t, std::shared_ptr<ShaderEffect> shader, const Rect& rect) noexcept;
|
||||
protected:
|
||||
ImageFilter() noexcept;
|
||||
|
||||
|
@ -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>& path, Brush& brush, const CmdList& cmdList);
|
||||
MaskPlayer(std::shared_ptr<Path>& 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>& path_;
|
||||
Brush& brush_;
|
||||
Pen& pen_;
|
||||
const CmdList& cmdList_;
|
||||
|
||||
using MaskPlaybackFunc = void(*)(MaskPlayer& palyer, const void* opItem, size_t leftOpAllocatorSize);
|
||||
private:
|
||||
static std::unordered_map<uint32_t, MaskPlaybackFunc> opPlaybackFuncLUT_;
|
||||
};
|
||||
|
||||
class DRAWING_API MaskCmdList : public CmdList {
|
||||
public:
|
||||
MaskCmdList() = default;
|
||||
@ -48,33 +77,9 @@ public:
|
||||
bool Playback(std::shared_ptr<Path>& path, Brush& brush) const;
|
||||
|
||||
bool Playback(std::shared_ptr<Path>& 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>& path, Brush& brush, const CmdList& cmdList);
|
||||
MaskPlayer(std::shared_ptr<Path>& 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>& path_;
|
||||
Brush& brush_;
|
||||
Pen& pen_;
|
||||
const CmdList& cmdList_;
|
||||
|
||||
using MaskPlaybackFunc = void(*)(MaskPlayer& palyer, const void* opItem);
|
||||
private:
|
||||
static std::unordered_map<uint32_t, MaskPlaybackFunc> 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>& path, const CmdList& cmdList) const;
|
||||
private:
|
||||
|
@ -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;
|
||||
|
@ -162,16 +162,16 @@ ImageFilter::ImageFilter(FilterType t, BlendMode mode, std::shared_ptr<ImageFilt
|
||||
}
|
||||
|
||||
std::shared_ptr<ImageFilter> ImageFilter::CreateShaderImageFilter(
|
||||
std::shared_ptr<ShaderEffect> shader)
|
||||
std::shared_ptr<ShaderEffect> shader, const Rect& rect)
|
||||
{
|
||||
return std::make_shared<ImageFilter>(ImageFilter::FilterType::SHADER, shader);
|
||||
return std::make_shared<ImageFilter>(ImageFilter::FilterType::SHADER, shader, rect);
|
||||
}
|
||||
|
||||
ImageFilter::ImageFilter(FilterType t, std::shared_ptr<ShaderEffect> shader) noexcept
|
||||
ImageFilter::ImageFilter(FilterType t, std::shared_ptr<ShaderEffect> shader, const Rect& rect) noexcept
|
||||
: ImageFilter()
|
||||
{
|
||||
type_ = t;
|
||||
impl_->InitWithShader(shader);
|
||||
impl_->InitWithShader(shader, rect);
|
||||
}
|
||||
|
||||
} // namespace Drawing
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
virtual bool Deserialize(std::shared_ptr<Data> data) = 0;
|
||||
virtual void InitWithBlend(BlendMode mode, std::shared_ptr<ImageFilter> background,
|
||||
std::shared_ptr<ImageFilter> foreground = nullptr) = 0;
|
||||
virtual void InitWithShader(std::shared_ptr<ShaderEffect> shader) = 0;
|
||||
virtual void InitWithShader(std::shared_ptr<ShaderEffect> shader, const Rect& rect) = 0;
|
||||
};
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
|
@ -191,13 +191,15 @@ void SkiaImageFilter::InitWithBlend(BlendMode mode, std::shared_ptr<ImageFilter>
|
||||
filter_ = SkImageFilters::Blend(static_cast<SkBlendMode>(mode), outer, inner);
|
||||
}
|
||||
|
||||
void SkiaImageFilter::InitWithShader(std::shared_ptr<ShaderEffect> shader)
|
||||
void SkiaImageFilter::InitWithShader(std::shared_ptr<ShaderEffect> shader, const Rect& rect)
|
||||
{
|
||||
sk_sp<SkShader> skShader = nullptr;
|
||||
if (shader != nullptr && shader->GetImpl<SkiaShaderEffect>() != nullptr) {
|
||||
skShader = shader->GetImpl<SkiaShaderEffect>()->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
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
const std::shared_ptr<ImageFilter> f) override;
|
||||
void InitWithBlend(BlendMode mode, std::shared_ptr<ImageFilter> background,
|
||||
std::shared_ptr<ImageFilter> foreground = nullptr) override;
|
||||
void InitWithShader(std::shared_ptr<ShaderEffect> shader) override;
|
||||
void InitWithShader(std::shared_ptr<ShaderEffect> shader, const Rect& rect) override;
|
||||
sk_sp<SkImageFilter> GetImageFilter() const;
|
||||
/*
|
||||
* @brief Update the member variable to filter, adaptation layer calls.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -36,15 +36,19 @@ std::shared_ptr<MaskCmdList> MaskCmdList::CreateFromData(const CmdListData& data
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
bool MaskCmdList::Playback(std::shared_ptr<Path>& 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<OpItem*>(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>& path, Brush& brush) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MaskCmdList::Playback(std::shared_ptr<Path>& path, Brush& brush) const
|
||||
{
|
||||
MaskPlayer player(path, brush, *this);
|
||||
return Playback(player);
|
||||
}
|
||||
|
||||
bool MaskCmdList::Playback(std::shared_ptr<Path>& 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<OpItem*>(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>& path, Brush& brush, const CmdList&
|
||||
MaskPlayer::MaskPlayer(std::shared_ptr<Path>& 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<const MaskBrushOpItem*>(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<const MaskPathOpItem*>(opItem);
|
||||
op->Playback(player.path_, player.cmdList_);
|
||||
}
|
||||
@ -172,9 +165,9 @@ void MaskPathOpItem::Playback(std::shared_ptr<Path>& 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<const MaskPenOpItem*>(opItem);
|
||||
op->Playback(player.pen_, player.cmdList_);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
virtual int32_t GetSupportedMetaDataKey(uint32_t screenId, std::vector<GraphicHDRMetadataKey> &keys) = 0;
|
||||
virtual int32_t Commit(uint32_t screenId, sptr<SyncFence> &fence) = 0;
|
||||
virtual int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr<SyncFence> &fence, int32_t &skipState,
|
||||
bool &needFlush) = 0;
|
||||
bool &needFlush, std::vector<uint32_t>& layers, std::vector<sptr<SyncFence>>& fences) = 0;
|
||||
/* set & get device screen info end */
|
||||
|
||||
/* set & get device layer info begin */
|
||||
|
@ -60,8 +60,8 @@ public:
|
||||
int32_t GetHDRCapabilityInfos(uint32_t screenId, GraphicHDRCapability &info) override;
|
||||
int32_t GetSupportedMetaDataKey(uint32_t screenId, std::vector<GraphicHDRMetadataKey> &keys) override;
|
||||
int32_t Commit(uint32_t screenId, sptr<SyncFence> &fence) override;
|
||||
int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr<SyncFence> &fence, int32_t &skipState,
|
||||
bool &needFlush) override;
|
||||
int32_t CommitAndGetReleaseFence(uint32_t screenId, sptr<SyncFence> &fence, int32_t &skipState, bool &needFlush,
|
||||
std::vector<uint32_t>& layers, std::vector<sptr<SyncFence>>& fences) override;
|
||||
/* set & get device screen info end */
|
||||
|
||||
/* set & get device layer info begin */
|
||||
|
@ -86,7 +86,8 @@ public:
|
||||
int32_t FlushScreen(std::vector<LayerPtr> &compClientLayers);
|
||||
int32_t SetScreenClientInfo(const FrameBufferEntry &fbEntry);
|
||||
int32_t Commit(sptr<SyncFence> &fbFence);
|
||||
int32_t CommitAndGetReleaseFence(sptr<SyncFence> &fbFence, int32_t &skipState, bool &needFlush);
|
||||
int32_t CommitAndGetReleaseFence(sptr<SyncFence> &fbFence, int32_t &skipState, bool &needFlush,
|
||||
std::vector<uint32_t>& layers, std::vector<sptr<SyncFence>>& fences);
|
||||
int32_t UpdateInfosAfterCommit(sptr<SyncFence> fbFence);
|
||||
int32_t ReleaseFramebuffer(const sptr<SyncFence>& releaseFence);
|
||||
std::map<LayerInfoPtr, sptr<SyncFence>> GetLayersReleaseFence();
|
||||
@ -121,6 +122,9 @@ private:
|
||||
uint32_t bufferCacheCountMax_ = 0;
|
||||
std::mutex layerMutex_;
|
||||
|
||||
std::vector<uint32_t> layersId_;
|
||||
std::vector<sptr<SyncFence>> fences_;
|
||||
|
||||
int32_t CreateLayer(uint64_t surfaceId, const LayerInfoPtr &layerInfo);
|
||||
void DeletePrevLayers();
|
||||
void ResetLayerStatus();
|
||||
|
@ -129,13 +129,15 @@ void HdiBackend::Repaint(const OutputPtr &output)
|
||||
|
||||
bool needFlush = false;
|
||||
int32_t skipState = INT32_MAX;
|
||||
std::vector<uint32_t> layers;
|
||||
std::vector<sptr<SyncFence>> fences;
|
||||
int32_t ret = output->PreProcessLayersComp();
|
||||
if (ret != GRAPHIC_DISPLAY_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
sptr<SyncFence> 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);
|
||||
}
|
||||
|
@ -399,18 +399,31 @@ int32_t HdiDeviceImpl::Commit(uint32_t screenId, sptr<SyncFence> &fence)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdiDeviceImpl::CommitAndGetReleaseFence(uint32_t screenId, sptr<SyncFence> &fence, int32_t &skipState,
|
||||
bool &needFlush)
|
||||
int32_t HdiDeviceImpl::CommitAndGetReleaseFence(uint32_t screenId, sptr<SyncFence> &fence,
|
||||
int32_t &skipState, bool &needFlush, std::vector<uint32_t>& layers, std::vector<sptr<SyncFence>>& fences)
|
||||
{
|
||||
ScopedBytrace bytrace(__func__);
|
||||
CHECK_FUNC(g_composer);
|
||||
int32_t fenceFd = -1;
|
||||
int32_t ret = g_composer->CommitAndGetReleaseFence(screenId, fenceFd, skipState, needFlush);
|
||||
std::vector<int32_t>fenceFds;
|
||||
|
||||
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 */
|
||||
|
@ -529,10 +529,13 @@ int32_t HdiOutput::Commit(sptr<SyncFence> &fbFence)
|
||||
return device_->Commit(screenId_, fbFence);
|
||||
}
|
||||
|
||||
int32_t HdiOutput::CommitAndGetReleaseFence(sptr<SyncFence> &fbFence, int32_t& skipState, bool& needFlush)
|
||||
int32_t HdiOutput::CommitAndGetReleaseFence(sptr<SyncFence> &fbFence, int32_t& skipState, bool& needFlush,
|
||||
std::vector<uint32_t>& layers, std::vector<sptr<SyncFence>>& 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<SyncFence> fbFence)
|
||||
@ -676,30 +679,18 @@ void HdiOutput::ReleaseLayers(sptr<SyncFence>& releaseFence)
|
||||
|
||||
std::map<LayerInfoPtr, sptr<SyncFence>> HdiOutput::GetLayersReleaseFence()
|
||||
{
|
||||
if (device_ == nullptr) {
|
||||
return {};
|
||||
}
|
||||
std::vector<uint32_t> layersId;
|
||||
std::vector<sptr<SyncFence>> 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<LayerInfoPtr, sptr<SyncFence>> res;
|
||||
std::unique_lock<std::mutex> 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;
|
||||
|
@ -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<SyncFence>&, int32_t&, bool&));
|
||||
MOCK_METHOD6(CommitAndGetReleaseFence, int32_t(uint32_t, sptr<SyncFence>&, int32_t&, bool&,
|
||||
std::vector<uint32_t>&, std::vector<sptr<SyncFence>>&));
|
||||
MOCK_METHOD0(Destroy, void());
|
||||
};
|
||||
} // namespace MockSys
|
||||
|
@ -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<SyncFence> fbFence = SyncFence::INVALID_FENCE;
|
||||
int32_t skipState = 0;
|
||||
bool needFlush = false;
|
||||
ASSERT_EQ(HdiOutputTest::hdiOutput_->CommitAndGetReleaseFence(fbFence, skipState, needFlush),
|
||||
std::vector<uint32_t> layers;
|
||||
std::vector<sptr<SyncFence>> fences;
|
||||
ASSERT_EQ(HdiOutputTest::hdiOutput_->CommitAndGetReleaseFence(fbFence, skipState, needFlush, layers, fences),
|
||||
GRAPHIC_DISPLAY_SUCCESS);
|
||||
}
|
||||
} // namespace
|
||||
|
@ -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<SyncFence>&, int32_t&, bool&));
|
||||
MOCK_METHOD6(CommitAndGetReleaseFence, int32_t(uint32_t, sptr<SyncFence>&, int32_t&, bool&,
|
||||
std::vector<uint32_t>&, std::vector<sptr<SyncFence>>&));
|
||||
MOCK_METHOD0(Destroy, void());
|
||||
};
|
||||
} // namespace Mock
|
||||
|
@ -152,6 +152,7 @@ private:
|
||||
#ifdef COMPOSER_SCHED_ENABLE
|
||||
void SubScribeSystemAbility(const std::string& threadName);
|
||||
#endif
|
||||
void NotifyMainThread();
|
||||
|
||||
sptr<VSyncSystemAbilityListener> saStatusChangeListener_ = nullptr;
|
||||
std::thread threadLoop_;
|
||||
|
@ -239,6 +239,7 @@ VSyncDistributor::~VSyncDistributor()
|
||||
#if defined(RS_ENABLE_DVSYNC)
|
||||
{
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
dvsync_->MarkPendingRNVIsProcess(false);
|
||||
dvsync_->RNVNotify();
|
||||
}
|
||||
#endif
|
||||
@ -323,6 +324,7 @@ void VSyncDistributor::WaitForVsyncOrRequest(std::unique_lock<std::mutex> &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<std::mutex> &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<std::mutex> 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<VSyncConnection> &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<std::mutex> locker(mutex_);
|
||||
|
||||
@ -689,11 +699,19 @@ VsyncError VSyncDistributor::RequestNextVSync(const sptr<VSyncConnection> &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<VSyncConnection> &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<VSyncConnection>& 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
|
||||
|
@ -61,6 +61,7 @@ void VSyncCallBackListener::OnReadable(int32_t fileDescriptor)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<std::mutex> locker(initMutex_);
|
||||
if (!init_) {
|
||||
return false;
|
||||
}
|
||||
return listener_->GetRNVFlag();
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -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
|
||||
|
@ -20,19 +20,19 @@
|
||||
#endif
|
||||
|
||||
#include "pixel_map_from_surface.h"
|
||||
#include <string>
|
||||
#include <scoped_bytrace.h>
|
||||
#include <string>
|
||||
#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<SurfaceBuffer> LocalDmaMemAlloc(const uint32_t &width, const uint32_
|
||||
RS_LOGE("Unsupport dma mem alloc");
|
||||
return nullptr;
|
||||
#else
|
||||
if (pixelmap == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
|
||||
BufferRequestConfig requestConfig = {
|
||||
.width = width,
|
||||
|
@ -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 = [
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <GLES3/gl32.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include "../../effectChain/include/ec_log.h"
|
||||
#include "ec_log.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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
|
||||
|
@ -250,11 +250,13 @@ void RSCanvasDrawingRenderNodeDrawable::ProcessCPURenderInBackgroundThread(std::
|
||||
std::shared_ptr<RSContext> 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<DrawableV2::RSCanvasDrawingRenderNodeDrawable*>(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<std::mutex> lock(this->imageMutex_);
|
||||
this->image_ = image;
|
||||
auto task = [ctx, nodeId = renderNode_->GetId()] () {
|
||||
std::lock_guard<std::mutex> lock(canvasDrawingDrawable->imageMutex_);
|
||||
canvasDrawingDrawable->image_ = image;
|
||||
auto task = [ctx, nodeId] () {
|
||||
if (UNLIKELY(!ctx)) {
|
||||
return;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -53,7 +53,7 @@ void RSRenderNodeShadowDrawable::Draw(Drawing::Canvas& canvas)
|
||||
return;
|
||||
}
|
||||
|
||||
SetSkipShadow(false);
|
||||
SetSkip(SkipType::NONE);
|
||||
DrawRangeImpl(canvas, rect, 0, shadowIndex + 1);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_);
|
||||
}
|
||||
|
@ -269,6 +269,15 @@ public:
|
||||
bool GetParallelCompositionEnabled();
|
||||
std::shared_ptr<HgmFrameRateManager> 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<pid_t,
|
||||
std::pair<uint64_t, std::vector<std::unique_ptr<RSTransactionData>>>>;
|
||||
@ -564,7 +575,7 @@ private:
|
||||
|
||||
// for dvsync (animate requestNextVSync after mark rsnotrendering)
|
||||
bool needRequestNextVsyncAnimate_ = false;
|
||||
bool hasMark_ = false;
|
||||
bool markRenderFlag_ = false;
|
||||
|
||||
bool forceUIFirstChanged_ = false;
|
||||
|
||||
|
@ -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<IVSyncConnection> RSRenderServiceConnection::CreateVSyncConnection(const st
|
||||
return conn;
|
||||
}
|
||||
|
||||
std::shared_ptr<Media::PixelMap> RSRenderServiceConnection::CreatePixelMapFromSurface(sptr<Surface> surface,
|
||||
const Rect &srcRect)
|
||||
{
|
||||
OHOS::Media::Rect rect = {
|
||||
.left = srcRect.x,
|
||||
.top = srcRect.y,
|
||||
.width = srcRect.w,
|
||||
.height = srcRect.h,
|
||||
};
|
||||
std::shared_ptr<Media::PixelMap> 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)
|
||||
{
|
||||
|
@ -81,6 +81,8 @@ private:
|
||||
uint64_t id,
|
||||
NodeId windowNodeId = 0) override;
|
||||
|
||||
std::shared_ptr<Media::PixelMap> CreatePixelMapFromSurface(sptr<Surface> 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<ScreenId> virtualScreenIds_;
|
||||
sptr<RSIScreenChangeCallback> screenChangeCallback_;
|
||||
sptr<VSyncDistributor> appVSyncDistributor_;
|
||||
|
||||
|
||||
#ifdef RS_PROFILER_ENABLED
|
||||
friend class RSProfiler;
|
||||
#endif
|
||||
|
@ -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());
|
||||
|
@ -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<RSBaseRenderNode> rootNode =
|
||||
|
@ -87,6 +87,8 @@ public:
|
||||
void ReleaseSurface();
|
||||
void AddToReleaseQueue(std::shared_ptr<Drawing::Surface>&& surface);
|
||||
|
||||
void DvsyncRequestNextVsync();
|
||||
|
||||
bool IsMainLooping() const
|
||||
{
|
||||
return mainLooping_.load();
|
||||
|
@ -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<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX;
|
||||
bool bgTransport = !node.GetAncoForceDoDirect() &&
|
||||
(static_cast<uint8_t>(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<RSSurfaceRenderNode>());
|
||||
curDisplayNode_->GetDirtySurfaceNodeMap().emplace(nodeId, node.ReinterpretCastTo<RSSurfaceRenderNode>());
|
||||
}
|
||||
UpdateSurfaceRenderNodeScale(node);
|
||||
// Due to the alpha is updated in PrepareChildren, so PrepareChildren
|
||||
@ -3434,6 +3438,11 @@ std::shared_ptr<Drawing::Image> RSUniRenderVisitor::GetCacheImageFromMirrorNode(
|
||||
|
||||
void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
|
||||
{
|
||||
curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
|
||||
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_ptr<RSDisplayRenderN
|
||||
}
|
||||
auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
|
||||
if (isUIFirst_ && surfaceDirtyManager->IsCurrentFrameDirty()) {
|
||||
dirtySurfaceNodeMap_.emplace(surfaceNode->GetId(), surfaceNode->ReinterpretCastTo<RSSurfaceRenderNode>());
|
||||
curDisplayNode_->GetDirtySurfaceNodeMap().emplace(
|
||||
surfaceNode->GetId(), surfaceNode->ReinterpretCastTo<RSSurfaceRenderNode>());
|
||||
}
|
||||
RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
|
||||
if (surfaceNode->IsTransparent()) {
|
||||
@ -4239,7 +4252,7 @@ void RSUniRenderVisitor::MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNod
|
||||
if ((hwcNode->IsLastFrameHardwareEnabled() || 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<RectI>& filterRec
|
||||
return filterDirty;
|
||||
}
|
||||
|
||||
void RSUniRenderVisitor::UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode>& node,
|
||||
std::vector<SurfaceDirtyMgrPair>& 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<RSSurfaceRenderNode>& node,
|
||||
std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes,
|
||||
std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager)
|
||||
@ -4289,32 +4335,8 @@ void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<R
|
||||
auto filterRects = node->GetChildrenNeedFilterRects();
|
||||
// collect valid hwc surface which is not intersected with filterRects
|
||||
std::vector<SurfaceDirtyMgrPair> 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<uint8_t>(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();
|
||||
|
@ -280,6 +280,9 @@ private:
|
||||
void UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode& displayNode);
|
||||
void UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
|
||||
std::vector<std::shared_ptr<RSSurfaceRenderNode>>& prevHwcEnabledNodes);
|
||||
void UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode>& node,
|
||||
std::vector<SurfaceDirtyMgrPair>& curHwcEnabledNodes);
|
||||
|
||||
void UpdateHardwareEnableList(std::vector<RectI>& filterRects,
|
||||
std::vector<std::shared_ptr<RSSurfaceRenderNode>>& validHwcNodes);
|
||||
// remove functions above when dirty region is enabled for foldable device
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <parameters.h>
|
||||
#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<HdiOutput> &output, bool connected, void *data)
|
||||
{
|
||||
if (output == nullptr) {
|
||||
|
@ -186,6 +186,7 @@ public:
|
||||
#ifdef RS_SUBSCRIBE_SENSOR_ENABLE
|
||||
virtual void HandlePostureData(const SensorEvent * const event) = 0;
|
||||
#endif
|
||||
virtual void ForceRefreshOneFrameIfNoRNV() = 0;
|
||||
};
|
||||
|
||||
sptr<RSScreenManager> CreateOrGetScreenManager();
|
||||
@ -353,6 +354,7 @@ public:
|
||||
#ifdef RS_SUBSCRIBE_SENSOR_ENABLE
|
||||
void HandlePostureData(const SensorEvent * const event) override;
|
||||
#endif
|
||||
void ForceRefreshOneFrameIfNoRNV() override;
|
||||
|
||||
private:
|
||||
RSScreenManager();
|
||||
|
@ -820,6 +820,46 @@ int RSRenderServiceConnectionStub::OnRemoteRequest(
|
||||
reply.WriteRemoteObject(conn->AsObject());
|
||||
break;
|
||||
}
|
||||
case static_cast<uint32_t>(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<IBufferProducer>(remoteObject);
|
||||
sptr<Surface> 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<Media::PixelMap> 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<uint32_t>(RSIRenderServiceConnectionInterfaceCode::GET_SCREEN_HDR_CAPABILITY): {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
|
@ -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",
|
||||
|
@ -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 <algorithm>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
|
||||
#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<int> 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
|
@ -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<typename T>
|
||||
struct Range {
|
||||
@ -172,6 +171,7 @@ public:
|
||||
class RSB_EXPORT RenderParticleColorParaType {
|
||||
public:
|
||||
Range<Color> colorVal_;
|
||||
DistributionType distribution_;
|
||||
ParticleUpdator updator_;
|
||||
Range<float> redRandom_;
|
||||
Range<float> greenRandom_;
|
||||
@ -179,14 +179,17 @@ public:
|
||||
Range<float> alphaRandom_;
|
||||
|
||||
std::vector<std::shared_ptr<ChangeInOverLife<Color>>> valChangeOverLife_;
|
||||
RenderParticleColorParaType(const Range<Color>& colorVal, const ParticleUpdator& updator,
|
||||
const Range<float>& redRandom, const Range<float>& greenRandom, const Range<float>& blueRandom,
|
||||
const Range<float>& alphaRandom, std::vector<std::shared_ptr<ChangeInOverLife<Color>>> valChangeOverLife)
|
||||
: colorVal_(colorVal), updator_(updator), redRandom_(redRandom), greenRandom_(greenRandom),
|
||||
blueRandom_(blueRandom), alphaRandom_(alphaRandom), valChangeOverLife_(std::move(valChangeOverLife))
|
||||
RenderParticleColorParaType(const Range<Color>& colorVal, const DistributionType& distribution,
|
||||
const ParticleUpdator& updator, const Range<float>& redRandom, const Range<float>& greenRandom,
|
||||
const Range<float>& blueRandom, const Range<float>& alphaRandom,
|
||||
std::vector<std::shared_ptr<ChangeInOverLife<Color>>> 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<ParticleRenderParams> 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<int>(std::round((end.GetRed() - start.GetRed()) * t)));
|
||||
result.SetGreen(start.GetGreen() + static_cast<int>(std::round((end.GetGreen() - start.GetGreen()) * t)));
|
||||
result.SetBlue(start.GetBlue() + static_cast<int>(std::round((end.GetBlue() - start.GetBlue()) * t)));
|
||||
result.SetAlpha(start.GetAlpha() + static_cast<int>(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<std::shared_ptr<RSRenderParticle>> renderParticleVector_;
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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>& emitterUpdater);
|
||||
void UpdateNoiseField(const std::shared_ptr<ParticleNoiseField>& particleNoiseField);
|
||||
const std::shared_ptr<RSRenderParticleSystem>& GetParticleSystem()
|
||||
{
|
||||
return particleSystem_;
|
||||
@ -59,6 +61,7 @@ private:
|
||||
std::vector<std::shared_ptr<ParticleRenderParams>> particlesRenderParams_;
|
||||
std::shared_ptr<RSRenderParticleSystem> particleSystem_;
|
||||
RSRenderParticleVector renderParticleVector_;
|
||||
std::shared_ptr<ParticleNoiseField> particleNoiseField_;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -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<int16_t> CalculateColorInt(const std::shared_ptr<RSRenderParticle>& particle, Vector4<int16_t> colorInt,
|
||||
Vector4<float> colorF, Vector4<float> colorSpeed, float deltaTime);
|
||||
|
||||
float UpdateCurveValue(
|
||||
void UpdateCurveValue(float& value,
|
||||
const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& valChangeOverLife, int64_t activeTime);
|
||||
|
||||
Color UpdateColorCurveValue(
|
||||
void UpdateColorCurveValue(Color& color,
|
||||
const std::vector<std::shared_ptr<ChangeInOverLife<Color>>>& valChangeOverLife, int64_t activeTime);
|
||||
|
||||
void UpdateColor(const std::shared_ptr<RSRenderParticle>& particle, float deltaTime);
|
||||
@ -45,11 +46,13 @@ public:
|
||||
|
||||
void UpdateAccelerationValue(const std::shared_ptr<RSRenderParticle>& particle, float deltaTime);
|
||||
|
||||
void UpdatePosition(const std::shared_ptr<RSRenderParticle>& particle, float deltaTime);
|
||||
void UpdatePosition(const std::shared_ptr<RSRenderParticle>& particle,
|
||||
const std::shared_ptr<ParticleNoiseField>& particleNoiseField, float deltaTime);
|
||||
|
||||
void UpdateActiveTime(const std::shared_ptr<RSRenderParticle>& particle, int64_t deltaTime);
|
||||
|
||||
void Update(const std::shared_ptr<RSRenderParticle>& particle, int64_t deltaTime);
|
||||
void Update(const std::shared_ptr<RSRenderParticle>& particle,
|
||||
const std::shared_ptr<ParticleNoiseField>& particleNoiseField, int64_t deltaTime);
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
bool IsFinish(const std::vector<std::shared_ptr<RSRenderParticle>>& activeParticles);
|
||||
void UpdateEmitter(
|
||||
const uint32_t& emitterIndex, const Vector2f& position, const Vector2f& emitSize, const int& emitRate);
|
||||
void UpdateNoiseField(const std::shared_ptr<ParticleNoiseField>& particleNoiseField);
|
||||
const std::vector<std::shared_ptr<RSRenderParticleEmitter>>& GetParticleEmitter()
|
||||
{
|
||||
return emitters_;
|
||||
@ -40,6 +41,7 @@ public:
|
||||
private:
|
||||
std::vector<std::shared_ptr<ParticleRenderParams>> particlesRenderParams_ = {};
|
||||
std::vector<std::shared_ptr<RSRenderParticleEmitter>> emitters_ = {};
|
||||
std::shared_ptr<ParticleNoiseField> particleNoiseField_;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -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<std::shared_ptr<EmitterUpdater>>,
|
||||
NodeId, std::shared_ptr<EmitterUpdater>, PropertyId, PropertyUpdateType))
|
||||
ADD_COMMAND(RSUpdatePropertyParticleNoiseField,
|
||||
ARG(RS_NODE, UPDATE_MODIFIER_NOISE_FIELD_PTR,
|
||||
RSNodeCommandHelper::UpdateModifier<std::shared_ptr<ParticleNoiseField>>,
|
||||
NodeId, std::shared_ptr<ParticleNoiseField>, PropertyId, PropertyUpdateType))
|
||||
ADD_COMMAND(RSUpdatePropertyShader,
|
||||
ARG(RS_NODE, UPDATE_MODIFIER_SHADER_PTR, RSNodeCommandHelper::UpdateModifier<std::shared_ptr<RSShader>>,
|
||||
NodeId, std::shared_ptr<RSShader>, PropertyId, PropertyUpdateType))
|
||||
|
@ -29,10 +29,11 @@ class RSB_EXPORT RSBackgroundThread final {
|
||||
public:
|
||||
static RSBackgroundThread& Instance();
|
||||
void PostTask(const std::function<void()>& task);
|
||||
void PostSyncTask(const std::function<void()>& 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<Drawing::GPUContext> GetShareGPUContext() const;
|
||||
#endif
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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<RSFilter> foregroundFilter_;
|
||||
std::shared_ptr<RSFilter> stagingForegroundFilter_;
|
||||
};
|
||||
|
||||
class RSForegroundColorDrawable : public RSPropertyDrawable {
|
||||
public:
|
||||
RSForegroundColorDrawable(std::shared_ptr<Drawing::DrawCmdList>&& drawCmdList)
|
||||
|
@ -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>& rsFilter);
|
||||
static void DrawFilter(Drawing::Canvas* canvas, const std::shared_ptr<RSFilter>& rsFilter,
|
||||
const std::unique_ptr<RSFilterCacheManager>& 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,
|
||||
|
@ -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<const RSRenderNode>&& node);
|
||||
@ -55,10 +61,7 @@ public:
|
||||
static SharedPtr GetDrawableById(NodeId id);
|
||||
static SharedPtr OnGenerateShadowDrawable(const std::shared_ptr<const RSRenderNode>& 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<NodeId, WeakPtr> RenderNodeDrawableCache;
|
||||
static inline std::mutex cacheMapMutex_;
|
||||
bool skipShadow_ = false;
|
||||
int8_t skipIndex_ = -1;
|
||||
};
|
||||
|
||||
} // namespace DrawableV2
|
||||
|
@ -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<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>;
|
||||
|
@ -100,6 +100,8 @@ DECLARE_NOANIMATABLE_MODIFIER(MotionBlurPara, std::shared_ptr<MotionBlurParam>,
|
||||
|
||||
DECLARE_NOANIMATABLE_MODIFIER(EmitterUpdater, std::shared_ptr<EmitterUpdater>, PARTICLE_EMITTER_UPDATER, Foreground)
|
||||
|
||||
DECLARE_NOANIMATABLE_MODIFIER(ParticleNoiseField, std::shared_ptr<ParticleNoiseField>, PARTICLE_NOISE_FIELD, Foreground)
|
||||
|
||||
DECLARE_NOANIMATABLE_MODIFIER(FrameGravity, Gravity, FRAME_GRAVITY, Appearance)
|
||||
|
||||
DECLARE_ANIMATABLE_MODIFIER(ClipRRect, RRect, CLIP_RRECT, Replace, Appearance, MEDIUM)
|
||||
|
@ -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<Drawing::Image> watermarkImg_ = nullptr;
|
||||
|
||||
bool needRequestNextVsyncAnimate_ = false;
|
||||
|
||||
int64_t onVsyncStartTime_ = TIMESTAMP_INITIAL;
|
||||
int64_t onVsyncStartTimeSteady_ = TIMESTAMP_INITIAL;
|
||||
bool isUniRenderAndOnVsync_ = false;
|
||||
|
@ -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 <screen_manager/screen_types.h>
|
||||
#include "screen_manager/rs_screen_info.h"
|
||||
#ifdef NEW_RENDER_CONTEXT
|
||||
@ -308,6 +309,11 @@ public:
|
||||
|
||||
void SetMainAndLeashSurfaceDirty(bool isDirty);
|
||||
|
||||
std::map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& GetDirtySurfaceNodeMap()
|
||||
{
|
||||
return dirtySurfaceNodeMap_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnSync() override;
|
||||
private:
|
||||
@ -357,6 +363,8 @@ private:
|
||||
|
||||
// Use in vulkan parallel rendering
|
||||
bool isParallelDisplayNode_ = false;
|
||||
|
||||
std::map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> dirtySurfaceNodeMap_;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -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 {
|
||||
|
@ -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<int> blendMode);
|
||||
int GetBlendOffscreenLayerCnt() const
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
bool HasOffscreenLayer() const;
|
||||
|
||||
// save/restore utils
|
||||
struct SaveStatus {
|
||||
@ -271,9 +270,8 @@ protected:
|
||||
Color envForegroundColor_;
|
||||
std::shared_ptr<CachedEffectData> effectData_;
|
||||
std::optional<int> blendMode_;
|
||||
bool hasOffscreenLayer_;
|
||||
};
|
||||
const std::stack<float>& GetAlphaStack();
|
||||
const std::stack<Env>& GetEnvStack();
|
||||
|
||||
bool OnFilter() const override;
|
||||
inline bool OnFilterWithBrush(Drawing::Brush& brush) const override
|
||||
|
@ -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<RSCanvasListener>& listener);
|
||||
// shapes
|
||||
|
@ -65,6 +65,9 @@ public:
|
||||
uint64_t id = 0,
|
||||
NodeId windowNodeId = 0) = 0;
|
||||
|
||||
virtual std::shared_ptr<Media::PixelMap> CreatePixelMapFromSurface(sptr<Surface> 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;
|
||||
|
@ -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,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#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<RSFilter>& backgroundFilter);
|
||||
void SetLinearGradientBlurPara(const std::shared_ptr<RSLinearGradientBlurPara>& para);
|
||||
void SetEmitterUpdater(const std::shared_ptr<EmitterUpdater>& para);
|
||||
void SetParticleNoiseField(const std::shared_ptr<ParticleNoiseField>& para);
|
||||
void SetDynamicLightUpRate(const std::optional<float>& rate);
|
||||
void SetDynamicLightUpDegree(const std::optional<float>& lightUpDegree);
|
||||
void SetDynamicDimDegree(const std::optional<float>& DimDegree);
|
||||
@ -239,6 +241,7 @@ public:
|
||||
const std::shared_ptr<RSFilter>& GetBackgroundFilter() const;
|
||||
const std::shared_ptr<RSLinearGradientBlurPara>& GetLinearGradientBlurPara() const;
|
||||
const std::shared_ptr<EmitterUpdater>& GetEmitterUpdater() const;
|
||||
const std::shared_ptr<ParticleNoiseField>& GetParticleNoiseField() const;
|
||||
void IfLinearGradientBlurInvalid();
|
||||
const std::shared_ptr<RSFilter>& GetFilter() const;
|
||||
const std::shared_ptr<MotionBlurParam>& GetMotionBlurPara() const;
|
||||
@ -522,6 +525,7 @@ private:
|
||||
std::shared_ptr<RSLinearGradientBlurPara> linearGradientBlurPara_ = nullptr;
|
||||
std::shared_ptr<MotionBlurParam> motionBlurPara_ = nullptr;
|
||||
std::shared_ptr<EmitterUpdater> emitterUpdater_ = nullptr;
|
||||
std::shared_ptr<ParticleNoiseField> particleNoiseField_ = nullptr;
|
||||
std::shared_ptr<RSBorder> border_ = nullptr;
|
||||
std::shared_ptr<RSBorder> outline_ = nullptr;
|
||||
std::shared_ptr<RSPath> clipPath_ = nullptr;
|
||||
|
@ -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<Color> colors_;
|
||||
|
@ -27,7 +27,7 @@ namespace Rosen {
|
||||
struct KawaseParameter {
|
||||
Drawing::Rect src;
|
||||
Drawing::Rect dst;
|
||||
int radius;
|
||||
int radius = 0;
|
||||
std::shared_ptr<Drawing::ColorFilter> 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<Drawing::Image>& checkedImage);
|
||||
void OutputOriginalImage(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
|
||||
const KawaseParameter& param);
|
||||
std::shared_ptr<Drawing::Image> ExecutePingPongBlur(Drawing::Canvas& canvas,
|
||||
const std::shared_ptr<Drawing::Image>& input, const KawaseParameter& kParam, const BlurParams& bParam) const;
|
||||
bool ApplyBlur(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
|
||||
const std::shared_ptr<Drawing::Image>& blurImage, const KawaseParameter& param) const;
|
||||
void ComputeRadiusAndScale(int radius);
|
||||
|
@ -52,6 +52,7 @@ class RSPath;
|
||||
class RSLinearGradientBlurPara;
|
||||
class MotionBlurParam;
|
||||
class EmitterUpdater;
|
||||
class ParticleNoiseField;
|
||||
template<typename T>
|
||||
class RenderParticleParaType;
|
||||
class EmitterConfig;
|
||||
@ -234,6 +235,7 @@ public:
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSLinearGradientBlurPara>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<MotionBlurParam>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<EmitterUpdater>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<ParticleNoiseField>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSFilter>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSMask>)
|
||||
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSImage>)
|
||||
|
@ -122,6 +122,8 @@ public:
|
||||
uint64_t id = 0,
|
||||
NodeId windowNodeId = 0);
|
||||
|
||||
std::shared_ptr<Media::PixelMap> CreatePixelMapFromSurfaceId(uint64_t surfaceid, const Rect &srcRect);
|
||||
|
||||
bool TakeSurfaceCapture(
|
||||
NodeId id, std::shared_ptr<SurfaceCaptureCallback> callback, float scaleX, float scaleY,
|
||||
SurfaceCaptureType surfaceCaptureType = SurfaceCaptureType::DEFAULT_CAPTURE, bool isSync = false);
|
||||
|
@ -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<float> 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
|
@ -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<uint64_t>::max() / NS_PER_MS) {
|
||||
return std::numeric_limits<uint64_t>::max();
|
||||
if (emitterConfig_.lifeTime_.start_ > std::numeric_limits<int64_t>::max() / NS_PER_MS) {
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return emitterConfig_.lifeTime_.start_ * NS_PER_MS;
|
||||
}
|
||||
|
||||
int64_t ParticleRenderParams::GetLifeTimeEndValue() const
|
||||
{
|
||||
if (emitterConfig_.lifeTime_.end_ > std::numeric_limits<uint64_t>::max() / NS_PER_MS) {
|
||||
return std::numeric_limits<uint64_t>::max();
|
||||
if (emitterConfig_.lifeTime_.end_ > std::numeric_limits<int64_t>::max() / NS_PER_MS) {
|
||||
return std::numeric_limits<int64_t>::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<int>(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<int>(std::round((end.GetRed() - start.GetRed()) * t)));
|
||||
result.SetGreen(start.GetGreen() + static_cast<int>(std::round((end.GetGreen() - start.GetGreen()) * t)));
|
||||
result.SetBlue(start.GetBlue() + static_cast<int>(std::round((end.GetBlue() - start.GetBlue()) * t)));
|
||||
result.SetAlpha(start.GetAlpha() + static_cast<int>(std::round((end.GetAlpha() - start.GetAlpha()) * t)));
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -17,12 +17,13 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<EmitterUpdat
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderParticleAnimation::UpdateNoiseField(const std::shared_ptr<ParticleNoiseField>& particleNoiseField)
|
||||
{
|
||||
if (particleNoiseField == nullptr) {
|
||||
return;
|
||||
} else if (particleNoiseField_ != nullptr && *particleNoiseField_ == *particleNoiseField) {
|
||||
return;
|
||||
}
|
||||
particleNoiseField_ = particleNoiseField;
|
||||
particleSystem_->UpdateNoiseField(particleNoiseField);
|
||||
}
|
||||
|
||||
void RSRenderParticleAnimation::OnAttach()
|
||||
{
|
||||
auto target = GetTarget();
|
||||
|
@ -47,10 +47,9 @@ Vector4<int16_t> RSRenderParticleEffector::CalculateColorInt(const std::shared_p
|
||||
return colorInt;
|
||||
}
|
||||
|
||||
float RSRenderParticleEffector::UpdateCurveValue(
|
||||
const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& valChangeOverLife, int64_t activeTime)
|
||||
void RSRenderParticleEffector::UpdateCurveValue(
|
||||
float& value, const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& 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<float>(activeTime - startTime) / static_cast<float>(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<std::shared_ptr<ChangeInOverLife<Color>>>& valChangeOverLife, int64_t activeTime)
|
||||
void RSRenderParticleEffector::UpdateColorCurveValue(
|
||||
Color& color, const std::vector<std::shared_ptr<ChangeInOverLife<Color>>>& 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<float>(activeTime - startTime) / static_cast<float>(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<RSRenderParticle>& particle, float deltaTime)
|
||||
@ -124,7 +114,7 @@ void RSRenderParticleEffector::UpdateColor(const std::shared_ptr<RSRenderParticl
|
||||
} else if (colorUpdator == ParticleUpdator::CURVE) {
|
||||
int64_t activeTime = particle->GetActiveTime() / 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_ptr<RSRenderParti
|
||||
} else if (opacityUpdator == ParticleUpdator::CURVE) {
|
||||
int64_t activeTime = particle->GetActiveTime() / 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_ptr<RSRenderParticl
|
||||
} else if (scaleUpdator == ParticleUpdator::CURVE) {
|
||||
int64_t activeTime = particle->GetActiveTime() / 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_ptr<RSRenderParticle
|
||||
} else if (spinUpdator == ParticleUpdator::CURVE) {
|
||||
int64_t activeTime = particle->GetActiveTime() / 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<RSRenderParticle>& particle, float deltaTime)
|
||||
void RSRenderParticleEffector::UpdatePosition(const std::shared_ptr<RSRenderParticle>& particle,
|
||||
const std::shared_ptr<ParticleNoiseField>& 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_ptr<RSRenderPart
|
||||
particle->SetVelocity(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<RSRenderPa
|
||||
}
|
||||
|
||||
// Apply effector to particle
|
||||
void RSRenderParticleEffector::Update(const std::shared_ptr<RSRenderParticle>& particle, int64_t deltaTime)
|
||||
void RSRenderParticleEffector::Update(const std::shared_ptr<RSRenderParticle>& particle,
|
||||
const std::shared_ptr<ParticleNoiseField>& particleNoiseField, int64_t deltaTime)
|
||||
{
|
||||
float dt = static_cast<float>(deltaTime) / NS_TO_S;
|
||||
UpdateAccelerationValue(particle, dt);
|
||||
@ -259,7 +257,7 @@ void RSRenderParticleEffector::Update(const std::shared_ptr<RSRenderParticle>& p
|
||||
UpdateOpacity(particle, dt);
|
||||
UpdateScale(particle, dt);
|
||||
UpdateSpin(particle, dt);
|
||||
UpdatePosition(particle, dt);
|
||||
UpdatePosition(particle, particleNoiseField, dt);
|
||||
UpdateActiveTime(particle, deltaTime);
|
||||
}
|
||||
|
||||
|
@ -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_ = particleNoiseField;
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -55,6 +55,14 @@ void RSBackgroundThread::PostTask(const std::function<void()>& task)
|
||||
handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
void RSBackgroundThread::PostSyncTask(const std::function<void()>& 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<Drawing::GPUContext> RSBackgroundThread::CreateShareGPUContext()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RSBackgroundThread::SetGrResourceFinishFlag(bool resourceFinish)
|
||||
void RSBackgroundThread::SetGrResourceFinishFlag(const bool& resourceFinish)
|
||||
{
|
||||
resourceFinish_ = resourceFinish;
|
||||
}
|
||||
|
@ -16,11 +16,13 @@
|
||||
#include "drawable/rs_drawable.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#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<int>(RSModifierType::MAX_RS_MODIFIER_TYPE);
|
||||
static const std::array<RSDrawableSlot, DIRTY_LUT_SIZE> g_propertyToDrawableLut = {
|
||||
static constexpr std::array<RSDrawableSlot, DIRTY_LUT_SIZE> g_propertyToDrawableLut = {
|
||||
RSDrawableSlot::INVALID, // INVALID
|
||||
RSDrawableSlot::CLIP_TO_BOUNDS, // BOUNDS
|
||||
RSDrawableSlot::FRAME_OFFSET, // FRAME
|
||||
@ -63,9 +65,9 @@ static const std::array<RSDrawableSlot, DIRTY_LUT_SIZE> 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<RSDrawableSlot, DIRTY_LUT_SIZE> 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<RSDrawableSlot, DIRTY_LUT_SIZE> 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<RSDrawableSlot, DIRTY_LUT_SIZE> 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<size_t>(RSModifierType::MAX_RS_MODIFIER_TYPE));
|
||||
static_assert(g_propertyToDrawableLut.back() != RSDrawableSlot {});
|
||||
|
||||
// Randomly check some LUT index and value
|
||||
static_assert(g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::USE_EFFECT)] == RSDrawableSlot::USE_EFFECT);
|
||||
static_assert(
|
||||
g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::FOREGROUND_COLOR)] == RSDrawableSlot::FOREGROUND_COLOR);
|
||||
static_assert(
|
||||
g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::CLIP_TO_FRAME)] == RSDrawableSlot::CLIP_TO_FRAME);
|
||||
static_assert(
|
||||
g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::USE_SHADOW_BATCHING)] == RSDrawableSlot::CHILDREN);
|
||||
static_assert(g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::TRANSITION)] == RSDrawableSlot::TRANSITION);
|
||||
static_assert(g_propertyToDrawableLut[static_cast<size_t>(RSModifierType::CHILDREN)] == RSDrawableSlot::CHILDREN);
|
||||
|
||||
template<RSModifierType type>
|
||||
static inline RSDrawable::Ptr ModifierGenerator(const RSRenderNode& node)
|
||||
{
|
||||
@ -164,6 +183,7 @@ static const std::array<RSDrawable::Generator, GEN_LUT_SIZE> g_drawableGenerator
|
||||
ModifierGenerator<RSModifierType::TRANSITION>, // 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<RSDrawable::Generator, GEN_LUT_SIZE> 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<RSDrawable::Generator, GEN_LUT_SIZE> 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<int>(RSColorBlendMode::NONE)) {
|
||||
// ClipToBounds if either 1. is surface node, 2. has explicit clip properties, 3. has blend mode
|
||||
bool shouldClipToBounds = node.IsInstanceOf<RSSurfaceRenderNode>() || properties.GetClipToBounds() ||
|
||||
properties.GetClipToRRect() || properties.GetClipBounds() != nullptr ||
|
||||
properties.GetColorBlendMode() != static_cast<int>(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<size_t>(slot)] = nullptr;
|
||||
}
|
||||
@ -422,34 +444,44 @@ std::unordered_set<RSDrawableSlot> 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<size_t>(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<size_t>(RSModifierType::BOUNDS))) {
|
||||
for (size_t i = 0; i < drawableVec.size(); i++) {
|
||||
if (drawableVec[i]) {
|
||||
dirtySlots.emplace(static_cast<RSDrawableSlot>(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<size_t>(RSModifierType::BOUNDS)) ||
|
||||
dirtyTypes.test(static_cast<size_t>(RSModifierType::CORNER_RADIUS))) {
|
||||
for (auto slot : boundsDirtyTypes) {
|
||||
if (drawableVec[static_cast<size_t>(slot)]) {
|
||||
dirtySlots.emplace(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1.4: if corner radius changed, update border and outline
|
||||
if (dirtyTypes.test(static_cast<size_t>(RSModifierType::CORNER_RADIUS))) {
|
||||
// border may should be updated with corner radius
|
||||
if (drawableVec[static_cast<size_t>(RSDrawableSlot::BORDER)]) {
|
||||
dirtySlots.emplace(RSDrawableSlot::BORDER);
|
||||
// if frame changed, mark affected drawables as dirty
|
||||
if (dirtySlots.count(RSDrawableSlot::FRAME_OFFSET)) {
|
||||
if (drawableVec[static_cast<size_t>(RSDrawableSlot::CLIP_TO_FRAME)]) {
|
||||
dirtySlots.emplace(RSDrawableSlot::CLIP_TO_FRAME);
|
||||
}
|
||||
|
||||
if (drawableVec[static_cast<size_t>(RSDrawableSlot::OUTLINE)]) {
|
||||
dirtySlots.emplace(RSDrawableSlot::OUTLINE);
|
||||
if (drawableVec[static_cast<size_t>(RSDrawableSlot::FOREGROUND_FILTER)]) {
|
||||
dirtySlots.emplace(RSDrawableSlot::FOREGROUND_FILTER);
|
||||
}
|
||||
}
|
||||
|
||||
if (dirtySlots.count(RSDrawableSlot::FOREGROUND_FILTER)) {
|
||||
dirtySlots.emplace(RSDrawableSlot::RESTORE_FOREGROUND_FILTER);
|
||||
}
|
||||
return dirtySlots;
|
||||
}
|
||||
|
||||
|
@ -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<RSEndBlendModeDrawable>();
|
||||
return std::make_shared<RSEndBlendModeDrawable>(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<const RSEndBlendModeDrawable>(shared_from_this());
|
||||
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
|
||||
auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(canvas);
|
||||
RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas);
|
||||
RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas, ptr->blendApplyType_);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ Drawing::RecordingCanvas::DrawFunc RSMaskShadowDrawable::CreateDrawFunc() const
|
||||
{
|
||||
auto ptr = std::static_pointer_cast<const RSMaskShadowDrawable>(shared_from_this());
|
||||
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
|
||||
Drawing::AutoCanvasRestore rst(*canvas, true);
|
||||
RSPropertyDrawableUtils::CeilMatrixTrans(canvas);
|
||||
ptr->drawCmdList_->Playback(*canvas);
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user