Merge branch 'master' of gitee.com:openharmony/graphic_graphic_2d into FixedTheFormatOfCode

Signed-off-by: changleipeng <changleipeng4@huawei.com>
This commit is contained in:
changleipeng 2024-04-19 02:24:07 +00:00 committed by Gitee
commit 769ebf1754
147 changed files with 2639 additions and 1121 deletions

View File

@ -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
}

View File

@ -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;

View File

@ -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 = {
}

View File

@ -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_;

View File

@ -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 {

View File

@ -23,7 +23,7 @@
#include "wm_common.h"
#include "../common/graphic_common.h"
#include "common/graphic_common.h"
#ifdef __cplusplus
namespace OHOS {

View File

@ -22,7 +22,7 @@
#include <map>
#endif
#include "../common/graphic_common.h"
#include "common/graphic_common.h"
#ifdef __cplusplus
namespace OHOS {

View File

@ -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") {

View File

@ -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", &paramsNApi);
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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
};

View File

@ -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;
};
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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>&)>

View File

@ -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;

View File

@ -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;
};
}

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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_);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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();

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 = [

View File

@ -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" {

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -53,7 +53,7 @@ void RSRenderNodeShadowDrawable::Draw(Drawing::Canvas& canvas)
return;
}
SetSkipShadow(false);
SetSkip(SkipType::NONE);
DrawRangeImpl(canvas, rect, 0, shadowIndex + 1);
}

View File

@ -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();
}

View File

@ -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_);
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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

View File

@ -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());

View File

@ -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 =

View File

@ -87,6 +87,8 @@ public:
void ReleaseSurface();
void AddToReleaseQueue(std::shared_ptr<Drawing::Surface>&& surface);
void DvsyncRequestNextVsync();
bool IsMainLooping() const
{
return mainLooping_.load();

View File

@ -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();

View File

@ -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

View File

@ -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) {

View File

@ -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();

View File

@ -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()) {

View File

@ -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",

View File

@ -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

View File

@ -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_;
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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)>;

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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_;

View File

@ -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);

View File

@ -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>)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_);
};
}

View File

@ -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