已合并
add border sdf shader #29675
add border sdf shader #29675
已合并
Rostellaria创建于 4月23日
31 个文件变更+606-5
Mrosen/modules/render_service_base/include/drawable/rs_property_drawable_foreground.h+2-0
@@ -204,6 +204,8 @@ public:
204private:204private:
205 static void DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas,205 static void DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas,
206 const std::shared_ptr<RSBorder>& border, const bool& isOutline);206 const std::shared_ptr<RSBorder>& border, const bool& isOutline);
207+ static void DrawBorderSDFShader(Drawing::Canvas& canvas, Drawing::Rect& rect, const bool& isOutline,
208+ std::shared_ptr<RSNGRenderShapeBase> shape, std::shared_ptr<RSNGRenderShaderBase> shader);
207};209};
208 210 
209class RSOutlineDrawable : public RSPropertyDrawable {211class RSOutlineDrawable : public RSPropertyDrawable {
Mrosen/modules/render_service_base/include/effect/rs_render_effect_template.h+1-0
@@ -119,6 +119,7 @@ public:
119 case RSNGEffectType::SDF_EDGE_LIGHT_EFFECT: return "SDFEdgeLightEffect";119 case RSNGEffectType::SDF_EDGE_LIGHT_EFFECT: return "SDFEdgeLightEffect";
120 case RSNGEffectType::MAGNIFIER: return "Magnifier";120 case RSNGEffectType::MAGNIFIER: return "Magnifier";
121 case RSNGEffectType::DISTORTION_COLLAPSE: return "DistortionCollapse";121 case RSNGEffectType::DISTORTION_COLLAPSE: return "DistortionCollapse";
122+ case RSNGEffectType::BORDER_SDF_SHADER: return "BorderSDFShader";
122 case RSNGEffectType::SPATIAL_POINT_LIGHT: return "SpatialPointLight";123 case RSNGEffectType::SPATIAL_POINT_LIGHT: return "SpatialPointLight";
123 case RSNGEffectType::SPATIAL_GLASS_EFFECT: return "SpatialGlassEffect";124 case RSNGEffectType::SPATIAL_GLASS_EFFECT: return "SpatialGlassEffect";
124 case RSNGEffectType::MOTION_BLUR: return "MotionBlur";125 case RSNGEffectType::MOTION_BLUR: return "MotionBlur";
Mrosen/modules/render_service_base/include/effect/rs_render_property_tag.h+1-0
@@ -134,6 +134,7 @@ enum class RSNGEffectType : int16_t {
134 DISTORT_CHROMA,134 DISTORT_CHROMA,
135 SDF_EDGE_LIGHT,135 SDF_EDGE_LIGHT,
136 SDF_EDGE_LIGHT_EFFECT,136 SDF_EDGE_LIGHT_EFFECT,
137+ BORDER_SDF_SHADER,
137 SPATIAL_POINT_LIGHT,138 SPATIAL_POINT_LIGHT,
138 SPATIAL_GLASS_EFFECT,139 SPATIAL_GLASS_EFFECT,
139 MOTION_BLUR,140 MOTION_BLUR,
Mrosen/modules/render_service_base/include/effect/rs_render_property_tag_def.in+8-0
@@ -573,6 +573,14 @@ DECLARE_ANIMATABLE_PROPERTY_TAG(DistortionCollapse, RBCorner, Vector2f);
573DECLARE_ANIMATABLE_PROPERTY_TAG(DistortionCollapse, LBCorner, Vector2f);573DECLARE_ANIMATABLE_PROPERTY_TAG(DistortionCollapse, LBCorner, Vector2f);
574DECLARE_ANIMATABLE_PROPERTY_TAG(DistortionCollapse, BarrelDistortion, Vector4f);574DECLARE_ANIMATABLE_PROPERTY_TAG(DistortionCollapse, BarrelDistortion, Vector4f);
575 575 
576+DECLARE_ANIMATABLE_PROPERTY_TAG(BorderSDFShader, Color, Vector4f);
577+DECLARE_ANIMATABLE_PROPERTY_TAG(BorderSDFShader, Width, float);
578+DECLARE_NONANIMATABLE_PROPERTY_TAG(BorderSDFShader, IsOutline, bool);
579+DECLARE_NONANIMATABLE_PROPERTY_TAG(BorderSDFShader, Style, int);
580+DECLARE_ANIMATABLE_PROPERTY_TAG(BorderSDFShader, DashWidth, float);
581+DECLARE_ANIMATABLE_PROPERTY_TAG(BorderSDFShader, DashGap, float);
582+DECLARE_NONANIMATABLE_PROPERTY_TAG(BorderSDFShader, Shape, std::shared_ptr<RSNGRenderShapeBase>);
583+ 
576DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, LightIntensity, float);584DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, LightIntensity, float);
577DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, LightPosition, Vector3f);585DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, LightPosition, Vector3f);
578DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, Attenuation, float);586DECLARE_ANIMATABLE_PROPERTY_TAG(SpatialPointLight, Attenuation, float);
Mrosen/modules/render_service_base/include/effect/rs_render_shader_def.in+11-1
@@ -284,6 +284,16 @@ DECLARE_SHADER(SDFEdgeLightEffect, SDF_EDGE_LIGHT_EFFECT,
284 ADD_PROPERTY_TAG(SDFEdgeLightEffect, SDFShape)284 ADD_PROPERTY_TAG(SDFEdgeLightEffect, SDFShape)
285);285);
286 286 
287+DECLARE_SHADER(BorderSDFShader, BORDER_SDF_SHADER,
288+ ADD_PROPERTY_TAG(BorderSDFShader, Color),
289+ ADD_PROPERTY_TAG(BorderSDFShader, Width),
290+ ADD_PROPERTY_TAG(BorderSDFShader, IsOutline),
291+ ADD_PROPERTY_TAG(BorderSDFShader, Style),
292+ ADD_PROPERTY_TAG(BorderSDFShader, DashWidth),
293+ ADD_PROPERTY_TAG(BorderSDFShader, DashGap),
294+ ADD_PROPERTY_TAG(BorderSDFShader, Shape)
295+);
296+ 
287DECLARE_SHADER(SpatialPointLight, SPATIAL_POINT_LIGHT,297DECLARE_SHADER(SpatialPointLight, SPATIAL_POINT_LIGHT,
288 ADD_PROPERTY_TAG(SpatialPointLight, LightIntensity),298 ADD_PROPERTY_TAG(SpatialPointLight, LightIntensity),
289 ADD_PROPERTY_TAG(SpatialPointLight, LightPosition),299 ADD_PROPERTY_TAG(SpatialPointLight, LightPosition),
@@ -322,4 +332,4 @@ DECLARE_SHADER(SpatialGlassEffect, SPATIAL_GLASS_EFFECT,
322 ADD_PROPERTY_TAG(SpatialGlassEffect, SdNeg),332 ADD_PROPERTY_TAG(SpatialGlassEffect, SdNeg),
323 ADD_PROPERTY_TAG(SpatialGlassEffect, SdfShape),333 ADD_PROPERTY_TAG(SpatialGlassEffect, SdfShape),
324 ADD_PROPERTY_TAG(SpatialGlassEffect, DepthImage)334 ADD_PROPERTY_TAG(SpatialGlassEffect, DepthImage)
325-);335+);
Mrosen/modules/render_service_base/include/modifier_ng/rs_modifier_ng_type.h+2-0
@@ -194,6 +194,7 @@ public:
194 case RSPropertyType::BORDER_STYLE: return "BorderStyle";194 case RSPropertyType::BORDER_STYLE: return "BorderStyle";
195 case RSPropertyType::BORDER_DASH_WIDTH: return "BorderDashWidth";195 case RSPropertyType::BORDER_DASH_WIDTH: return "BorderDashWidth";
196 case RSPropertyType::BORDER_DASH_GAP: return "BorderDashGap";196 case RSPropertyType::BORDER_DASH_GAP: return "BorderDashGap";
197+ case RSPropertyType::BORDER_SDF_SHADER: return "BorderSDFShader";
197 case RSPropertyType::BACKGROUND_FILTER: return "BackgroundFilter";198 case RSPropertyType::BACKGROUND_FILTER: return "BackgroundFilter";
198 case RSPropertyType::LINEAR_GRADIENT_BLUR_PARA: return "LinearGradientBlurPara";199 case RSPropertyType::LINEAR_GRADIENT_BLUR_PARA: return "LinearGradientBlurPara";
199 case RSPropertyType::DYNAMIC_LIGHT_UP_RATE: return "DynamicLightUpRate";200 case RSPropertyType::DYNAMIC_LIGHT_UP_RATE: return "DynamicLightUpRate";
@@ -257,6 +258,7 @@ public:
257 case RSPropertyType::OUTLINE_DASH_WIDTH: return "OutlineDashWidth";258 case RSPropertyType::OUTLINE_DASH_WIDTH: return "OutlineDashWidth";
258 case RSPropertyType::OUTLINE_DASH_GAP: return "OutlineDashGap";259 case RSPropertyType::OUTLINE_DASH_GAP: return "OutlineDashGap";
259 case RSPropertyType::OUTLINE_RADIUS: return "OutlineRadius";260 case RSPropertyType::OUTLINE_RADIUS: return "OutlineRadius";
261+ case RSPropertyType::OUTLINE_SDF_SHADER: return "OutlineSDFShader";
260 case RSPropertyType::GREY_COEF: return "GreyCoef";262 case RSPropertyType::GREY_COEF: return "GreyCoef";
G
Ggaoweihua4月27日

做好验证

likedislike
261 case RSPropertyType::LIGHT_INTENSITY: return "LightIntensity";263 case RSPropertyType::LIGHT_INTENSITY: return "LightIntensity";
262 case RSPropertyType::LIGHT_COLOR: return "LightColor";264 case RSPropertyType::LIGHT_COLOR: return "LightColor";
Mrosen/modules/render_service_base/include/modifier_ng/rs_property_ng_type.in+2-0
@@ -197,5 +197,7 @@ X(COLOR_ADAPTIVE)
197X(SHADOW_DISABLE_SDF_BLUR)197X(SHADOW_DISABLE_SDF_BLUR)
198X(HDR_COLOR_HEADROOM)198X(HDR_COLOR_HEADROOM)
199X(PARTICLE_FIELDS)199X(PARTICLE_FIELDS)
200+X(BORDER_SDF_SHADER)
201+X(OUTLINE_SDF_SHADER)
200X(DOUBLE_SIDED)202X(DOUBLE_SIDED)
201X(CHILDREN)203X(CHILDREN)
Mrosen/modules/render_service_base/include/property/rs_properties.h+4-0
@@ -337,11 +337,13 @@ public:
337 void SetBorderStyle(Vector4<uint32_t> style);337 void SetBorderStyle(Vector4<uint32_t> style);
338 void SetBorderDashWidth(const Vector4f& dashWidth);338 void SetBorderDashWidth(const Vector4f& dashWidth);
339 void SetBorderDashGap(const Vector4f& dashGap);339 void SetBorderDashGap(const Vector4f& dashGap);
340+ void SetBorderSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& renderShader);
340 Vector4<Color> GetBorderColor() const;341 Vector4<Color> GetBorderColor() const;
341 Vector4f GetBorderWidth() const;342 Vector4f GetBorderWidth() const;
342 Vector4<uint32_t> GetBorderStyle() const;343 Vector4<uint32_t> GetBorderStyle() const;
343 Vector4f GetBorderDashWidth() const;344 Vector4f GetBorderDashWidth() const;
344 Vector4f GetBorderDashGap() const;345 Vector4f GetBorderDashGap() const;
346+ std::shared_ptr<RSNGRenderShaderBase> GetBorderSDFShader() const;
345 const std::shared_ptr<RSBorder>& GetBorder() const;347 const std::shared_ptr<RSBorder>& GetBorder() const;
346 void SetOutlineColor(Vector4<Color> color);348 void SetOutlineColor(Vector4<Color> color);
347 void SetOutlineWidth(Vector4f width);349 void SetOutlineWidth(Vector4f width);
@@ -349,12 +351,14 @@ public:
349 void SetOutlineDashWidth(const Vector4f& dashWidth);351 void SetOutlineDashWidth(const Vector4f& dashWidth);
350 void SetOutlineDashGap(const Vector4f& dashGap);352 void SetOutlineDashGap(const Vector4f& dashGap);
351 void SetOutlineRadius(Vector4f radius);353 void SetOutlineRadius(Vector4f radius);
354+ void SetOutlineSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& renderShader);
352 Vector4<Color> GetOutlineColor() const;355 Vector4<Color> GetOutlineColor() const;
353 Vector4f GetOutlineWidth() const;356 Vector4f GetOutlineWidth() const;
354 Vector4<uint32_t> GetOutlineStyle() const;357 Vector4<uint32_t> GetOutlineStyle() const;
355 Vector4f GetOutlineDashWidth() const;358 Vector4f GetOutlineDashWidth() const;
356 Vector4f GetOutlineDashGap() const;359 Vector4f GetOutlineDashGap() const;
357 Vector4f GetOutlineRadius() const;360 Vector4f GetOutlineRadius() const;
361+ std::shared_ptr<RSNGRenderShaderBase> GetOutlineSDFShader() const;
358 const std::shared_ptr<RSBorder>& GetOutline() const362 const std::shared_ptr<RSBorder>& GetOutline() const
359 {363 {
360 return outline_;364 return outline_;
Mrosen/modules/render_service_base/include/render/rs_border.h+6-0
@@ -33,6 +33,8 @@
33 33 
34namespace OHOS {34namespace OHOS {
35namespace Rosen {35namespace Rosen {
36+class RSNGRenderShaderBase;
37+ 
36enum class BorderStyle : uint32_t {38enum class BorderStyle : uint32_t {
37 SOLID = 0,39 SOLID = 0,
38 DASHED,40 DASHED,
@@ -72,11 +74,13 @@ public:
72 void SetStyle(BorderStyle style);74 void SetStyle(BorderStyle style);
73 void SetDashWidth(float dashWidth);75 void SetDashWidth(float dashWidth);
74 void SetDashGap(float dashGap);76 void SetDashGap(float dashGap);
77+ void SetSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& shader);
75 Color GetColor(int idx = RSBorder::LEFT) const;78 Color GetColor(int idx = RSBorder::LEFT) const;
76 float GetWidth(int idx = RSBorder::LEFT) const;79 float GetWidth(int idx = RSBorder::LEFT) const;
77 BorderStyle GetStyle(int idx = RSBorder::LEFT) const;80 BorderStyle GetStyle(int idx = RSBorder::LEFT) const;
78 float GetDashWidth(int idx = RSBorder::LEFT) const;81 float GetDashWidth(int idx = RSBorder::LEFT) const;
79 float GetDashGap(int idx = RSBorder::LEFT) const;82 float GetDashGap(int idx = RSBorder::LEFT) const;
83+ std::shared_ptr<RSNGRenderShaderBase> GetSDFShader() const;
80 84 
81 void SetColorFour(const Vector4<Color>& color);85 void SetColorFour(const Vector4<Color>& color);
82 void SetWidthFour(const Vector4f& width);86 void SetWidthFour(const Vector4f& width);
@@ -131,6 +135,8 @@ private:
131 // Dash params dashWidth and dashGap135 // Dash params dashWidth and dashGap
132 std::vector<float> dashWidth_;136 std::vector<float> dashWidth_;
133 std::vector<float> dashGap_;137 std::vector<float> dashGap_;
138+ // Shader for SDFShape border
139+ std::shared_ptr<RSNGRenderShaderBase> sdfShader_;
134 140 
135 // only be used by outline, innerBorder(border_) uses corner radius.141 // only be used by outline, innerBorder(border_) uses corner radius.
136 Vector4f radius_;142 Vector4f radius_;
Mrosen/modules/render_service_base/src/drawable/rs_property_drawable_foreground.cpp+41-0
@@ -495,9 +495,50 @@ bool RSBorderDrawable::OnUpdate(const RSRenderNode& node)
495 return true;495 return true;
496}496}
497 497 
498+namespace {
499+bool PreprocessBorderSDFShader(Drawing::Rect& rect, bool isOutline, std::shared_ptr<RSNGRenderShapeBase> shape,
500+ std::shared_ptr<RSNGRenderShaderBase> shader)
501+{
502+ switch (shader->GetType()) {
503+ case RSNGEffectType::BORDER_SDF_SHADER:
chensiyi_CE
chensiyi_CEchensiyi_CE4月30日

就一个case 不建议加switch。shader->GetType() !=RSNGEffectType::BORDER_SDF_SHADER: 卫语句返回即可。

likedislike
chensiyi_CE
chensiyi_CE
4月30日 评论:
Rostellaria
Rostellaria
4月30日 评论:
504+ std::static_pointer_cast<RSNGRenderBorderSDFShader>(shader)->
505+ Setter<BorderSDFShaderShapeRenderTag>(shape, PropertyUpdateType::UPDATE_TYPE_ONLY_VALUE);
506+ std::static_pointer_cast<RSNGRenderBorderSDFShader>(shader)->
507+ Setter<BorderSDFShaderIsOutlineRenderTag>(isOutline);
508+ if (isOutline) {
509+ float width = std::static_pointer_cast<RSNGRenderBorderSDFShader>(shader)->
510+ Getter<BorderSDFShaderWidthRenderTag>()->Get();
511+ rect.MakeOutset(width, width);
512+ }
513+ return true;
514+ default:
515+ return false;
516+ }
517+}
518+}
519+ 
520+void RSBorderDrawable::DrawBorderSDFShader(Drawing::Canvas& canvas, Drawing::Rect& rect, const bool& isOutline,
521+ std::shared_ptr<RSNGRenderShapeBase> shape, std::shared_ptr<RSNGRenderShaderBase> shader)
522+{
523+ if (!PreprocessBorderSDFShader(rect, isOutline, shape, shader)) {
524+ RS_LOGE("RSBorderDrawable::DrawBorderSDFShader PreprocessBorderSDFShader fail");
525+ return;
526+ }
527+ auto visualEffectContainer = std::make_shared<Drawing::GEVisualEffectContainer>();
528+ shader->AppendToGEContainer(visualEffectContainer);
529+ auto geRender = std::make_shared<GraphicsEffectEngine::GERender>();
530+ geRender->DrawShaderEffect(canvas, *visualEffectContainer, rect);
531+}
532+ 
498void RSBorderDrawable::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas,533void RSBorderDrawable::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas,
499 const std::shared_ptr<RSBorder>& border, const bool& isOutline)534 const std::shared_ptr<RSBorder>& border, const bool& isOutline)
500{535{
536+ if (properties.GetSDFShape() && border->GetSDFShader()) {
537+ Drawing::Rect sdfShaderRect(0.f, 0.f, properties.GetFrameWidth(), properties.GetFrameHeight());
538+ RSBorderDrawable::DrawBorderSDFShader(canvas, sdfShaderRect, isOutline,
539+ properties.GetSDFShape(), border->GetSDFShader());
540+ return;
541+ }
501 Drawing::Brush brush;542 Drawing::Brush brush;
502 Drawing::Pen pen;543 Drawing::Pen pen;
503 brush.SetAntiAlias(true);544 brush.SetAntiAlias(true);
Mrosen/modules/render_service_base/src/effect/rs_render_shader_base.cpp+4-0
@@ -100,6 +100,10 @@ static std::unordered_map<RSNGEffectType, ShaderCreator> creatorLUT = {
100 return std::make_shared<RSNGRenderSDFEdgeLightEffect>();100 return std::make_shared<RSNGRenderSDFEdgeLightEffect>();
101 }101 }
102 },102 },
103+ {RSNGEffectType::BORDER_SDF_SHADER, [] {
104+ return std::make_shared<RSNGRenderBorderSDFShader>();
105+ }
106+ },
103 {RSNGEffectType::SPATIAL_POINT_LIGHT, [] {107 {RSNGEffectType::SPATIAL_POINT_LIGHT, [] {
104 return std::make_shared<RSNGRenderSpatialPointLight>();108 return std::make_shared<RSNGRenderSpatialPointLight>();
105 }109 }
Mrosen/modules/render_service_base/src/modifier_ng/appearance/rs_border_render_modifier.cpp+3-0
@@ -26,6 +26,9 @@ const RSBorderRenderModifier::LegacyPropertyApplierMap RSBorderRenderModifier::L
26 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetBorderDashWidth> },26 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetBorderDashWidth> },
27 { RSPropertyType::BORDER_DASH_GAP,27 { RSPropertyType::BORDER_DASH_GAP,
28 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetBorderDashGap> },28 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetBorderDashGap> },
29+ { RSPropertyType::BORDER_SDF_SHADER,
30+ RSRenderModifier::PropertyApplyHelper<std::shared_ptr<RSNGRenderShaderBase>,
31+ &RSProperties::SetBorderSDFShader> },
29};32};
30 33 
31void RSBorderRenderModifier::ResetProperties(RSProperties& properties)34void RSBorderRenderModifier::ResetProperties(RSProperties& properties)
Mrosen/modules/render_service_base/src/modifier_ng/appearance/rs_outline_render_modifier.cpp+3-0
@@ -28,6 +28,9 @@ const RSOutlineRenderModifier::LegacyPropertyApplierMap RSOutlineRenderModifier:
28 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetOutlineDashGap> },28 RSRenderModifier::PropertyApplyHelper<Vector4f, &RSProperties::SetOutlineDashGap> },
29 { RSPropertyType::OUTLINE_RADIUS, RSRenderModifier::PropertyApplyHelperAdd<Vector4f,29 { RSPropertyType::OUTLINE_RADIUS, RSRenderModifier::PropertyApplyHelperAdd<Vector4f,
30 &RSProperties::SetOutlineRadius, &RSProperties::GetOutlineRadius> },30 &RSProperties::SetOutlineRadius, &RSProperties::GetOutlineRadius> },
31+ { RSPropertyType::OUTLINE_SDF_SHADER,
32+ RSRenderModifier::PropertyApplyHelper<std::shared_ptr<RSNGRenderShaderBase>,
33+ &RSProperties::SetOutlineSDFShader> },
31};34};
32 35 
33void RSOutlineRenderModifier::ResetProperties(RSProperties& properties)36void RSOutlineRenderModifier::ResetProperties(RSProperties& properties)
Mrosen/modules/render_service_base/src/pipeline/rs_union_render_node.cpp+2-2
@@ -104,8 +104,8 @@ void RSUnionRenderNode::ProcessSDFShape(RSDirtyRegionManager& dirtyManager)
104 SDFUnionOpShapeShapeYRenderTag>(shapeQueue);104 SDFUnionOpShapeShapeYRenderTag>(shapeQueue);
105 }105 }
106 }106 }
107- if (!GetRenderProperties().GetSDFShape() ||107+ if (root && (!GetRenderProperties().GetSDFShape() ||
108- GetRenderProperties().GetSDFShape()->CalculateHash() != root->CalculateHash()) {108+ GetRenderProperties().GetSDFShape()->CalculateHash() != root->CalculateHash())) {
109 GetMutableRenderProperties().InternalSetSDFShape(root);109 GetMutableRenderProperties().InternalSetSDFShape(root);
110 dirtyManager.MergeDirtyRect(GetAbsDrawRect());110 dirtyManager.MergeDirtyRect(GetAbsDrawRect());
111 UpdateDrawableAfterPostPrepare(ModifierNG::RSModifierType::CLIP_TO_BOUNDS);111 UpdateDrawableAfterPostPrepare(ModifierNG::RSModifierType::CLIP_TO_BOUNDS);
Mrosen/modules/render_service_base/src/property/rs_properties.cpp+30-0
@@ -1009,6 +1009,16 @@ void RSProperties::SetBorderDashGap(const Vector4f& dashGap)
1009 contentDirty_ = true;1009 contentDirty_ = true;
1010}1010}
1011 1011 
1012+void RSProperties::SetBorderSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& renderShader)
1013+{
1014+ if (!border_) {
1015+ border_ = std::make_shared<RSBorder>();
1016+ }
1017+ border_->SetSDFShader(renderShader);
1018+ SetDirty();
1019+ contentDirty_ = true;
1020+}
1021+ 
1012Vector4<Color> RSProperties::GetBorderColor() const1022Vector4<Color> RSProperties::GetBorderColor() const
1013{1023{
1014 return border_ ? border_->GetColorFour() : Vector4<Color>(RgbPalette::Transparent());1024 return border_ ? border_->GetColorFour() : Vector4<Color>(RgbPalette::Transparent());
@@ -1034,6 +1044,11 @@ Vector4f RSProperties::GetBorderDashGap() const
1034 return border_ ? border_->GetDashGapFour() : Vector4f(0.f);1044 return border_ ? border_->GetDashGapFour() : Vector4f(0.f);
1035}1045}
1036 1046 
1047+std::shared_ptr<RSNGRenderShaderBase> RSProperties::GetBorderSDFShader() const
1048+{
1049+ return border_ ? border_->GetSDFShader() : nullptr;
1050+}
1051+ 
1037const std::shared_ptr<RSBorder>& RSProperties::GetBorder() const1052const std::shared_ptr<RSBorder>& RSProperties::GetBorder() const
1038{1053{
1039 return border_;1054 return border_;
@@ -1106,6 +1121,16 @@ void RSProperties::SetOutlineRadius(Vector4f radius)
1106 contentDirty_ = true;1121 contentDirty_ = true;
1107}1122}
1108 1123 
1124+void RSProperties::SetOutlineSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& renderShader)
1125+{
1126+ if (!outline_) {
1127+ outline_ = std::make_shared<RSBorder>(true);
1128+ }
1129+ outline_->SetSDFShader(renderShader);
1130+ SetDirty();
1131+ contentDirty_ = true;
1132+}
1133+ 
1109Vector4<Color> RSProperties::GetOutlineColor() const1134Vector4<Color> RSProperties::GetOutlineColor() const
1110{1135{
1111 return outline_ ? outline_->GetColorFour() : Vector4<Color>(RgbPalette::Transparent());1136 return outline_ ? outline_->GetColorFour() : Vector4<Color>(RgbPalette::Transparent());
@@ -1136,6 +1161,11 @@ Vector4f RSProperties::GetOutlineRadius() const
1136 return outline_ ? outline_->GetRadiusFour() : Vector4fZero;1161 return outline_ ? outline_->GetRadiusFour() : Vector4fZero;
1137}1162}
1138 1163 
1164+std::shared_ptr<RSNGRenderShaderBase> RSProperties::GetOutlineSDFShader() const
1165+{
1166+ return outline_ ? outline_->GetSDFShader() : nullptr;
1167+}
1168+ 
1139void RSProperties::SetForegroundEffectRadius(const float foregroundEffectRadius)1169void RSProperties::SetForegroundEffectRadius(const float foregroundEffectRadius)
1140{1170{
1141 GetEffect().foregroundEffectRadius_ = foregroundEffectRadius;1171 GetEffect().foregroundEffectRadius_ = foregroundEffectRadius;
Mrosen/modules/render_service_base/src/render/rs_border.cpp+16-2
@@ -16,6 +16,7 @@
16#include "render/rs_border.h"16#include "render/rs_border.h"
17 17 
18#include "draw/path.h"18#include "draw/path.h"
19+#include "effect/rs_render_shader_base.h"
19#include "platform/common/rs_log.h"20#include "platform/common/rs_log.h"
20 21 
21namespace OHOS {22namespace OHOS {
@@ -932,17 +933,30 @@ std::string RSBorder::ToString() const
932 for (auto style : styles_) {933 for (auto style : styles_) {
933 ss << static_cast<uint32_t>(style) << ", ";934 ss << static_cast<uint32_t>(style) << ", ";
934 }935 }
936+ if (sdfShader_) {
937+ ss << "sdfShader: " << sdfShader_->Dump() << ", ";
938+ }
935 std::string output = ss.str();939 std::string output = ss.str();
936 return output;940 return output;
937}941}
938 942 
939bool RSBorder::HasBorder() const943bool RSBorder::HasBorder() const
940{944{
941- return !colors_.empty() && !widths_.empty() && !styles_.empty() &&945+ return sdfShader_ != nullptr || (!colors_.empty() && !widths_.empty() && !styles_.empty() &&
942 !std::all_of(colors_.begin(), colors_.end(), [](const Color& color) { return color.GetAlpha() == 0; }) &&946 !std::all_of(colors_.begin(), colors_.end(), [](const Color& color) { return color.GetAlpha() == 0; }) &&
943 !std::all_of(widths_.begin(), widths_.end(), [](const float& width) { return width <= 0.f; }) &&947 !std::all_of(widths_.begin(), widths_.end(), [](const float& width) { return width <= 0.f; }) &&
944 !std::all_of(948 !std::all_of(
945- styles_.begin(), styles_.end(), [](const BorderStyle& style) { return style == BorderStyle::NONE; });949+ styles_.begin(), styles_.end(), [](const BorderStyle& style) { return style == BorderStyle::NONE; }));
950+}
951+ 
952+void RSBorder::SetSDFShader(const std::shared_ptr<RSNGRenderShaderBase>& shader)
953+{
954+ sdfShader_ = shader;
955+}
956+ 
957+std::shared_ptr<RSNGRenderShaderBase> RSBorder::GetSDFShader() const
958+{
959+ return sdfShader_;
946}960}
947} // namespace Rosen961} // namespace Rosen
948} // namespace OHOS962} // namespace OHOS
Mrosen/modules/render_service_client/core/modifier_ng/appearance/rs_border_modifier.cpp+10-0
@@ -65,4 +65,14 @@ Vector4f RSBorderModifier::GetBorderDashGap() const
65{65{
66 return Getter<Vector4f>(RSPropertyType::BORDER_DASH_GAP, {});66 return Getter<Vector4f>(RSPropertyType::BORDER_DASH_GAP, {});
67}67}
68+ 
69+void RSBorderModifier::SetBorderSDFShader(const std::shared_ptr<RSNGShaderBase>& shader)
70+{
71+ Setter<RSProperty, std::shared_ptr<RSNGShaderBase>>(RSPropertyType::BORDER_SDF_SHADER, shader);
72+}
73+ 
74+std::shared_ptr<RSNGShaderBase> RSBorderModifier::GetBorderSDFShader() const
75+{
76+ return Getter<std::shared_ptr<RSNGShaderBase>>(RSPropertyType::BORDER_SDF_SHADER, nullptr);
77+}
68} // namespace OHOS::Rosen::ModifierNG78} // namespace OHOS::Rosen::ModifierNG
Mrosen/modules/render_service_client/core/modifier_ng/appearance/rs_border_modifier.h+2-0
@@ -40,6 +40,8 @@ public:
40 Vector4f GetBorderDashWidth() const;40 Vector4f GetBorderDashWidth() const;
41 void SetBorderDashGap(const Vector4f& dashGap);41 void SetBorderDashGap(const Vector4f& dashGap);
42 Vector4f GetBorderDashGap() const;42 Vector4f GetBorderDashGap() const;
43+ void SetBorderSDFShader(const std::shared_ptr<RSNGShaderBase>& shader);
44+ std::shared_ptr<RSNGShaderBase> GetBorderSDFShader() const;
43};45};
44} // namespace OHOS::Rosen::ModifierNG46} // namespace OHOS::Rosen::ModifierNG
45#endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_NG_APPEARANCE_RS_BORDER_MODIFIER_H47#endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_NG_APPEARANCE_RS_BORDER_MODIFIER_H
Mrosen/modules/render_service_client/core/modifier_ng/appearance/rs_outline_modifier.cpp+10-0
@@ -75,4 +75,14 @@ const Vector4f RSOutlineModifier::GetOutlineRadius() const
75{75{
76 return Getter(RSPropertyType::OUTLINE_RADIUS, Vector4f(0.f));76 return Getter(RSPropertyType::OUTLINE_RADIUS, Vector4f(0.f));
77}77}
78+ 
79+void RSOutlineModifier::SetOutlineSDFShader(const std::shared_ptr<RSNGShaderBase>& shader)
80+{
81+ Setter<RSProperty, std::shared_ptr<RSNGShaderBase>>(RSPropertyType::OUTLINE_SDF_SHADER, shader);
82+}
83+ 
84+std::shared_ptr<RSNGShaderBase> RSOutlineModifier::GetOutlineSDFShader() const
85+{
86+ return Getter<std::shared_ptr<RSNGShaderBase>>(RSPropertyType::OUTLINE_SDF_SHADER, nullptr);
87+}
78} // namespace OHOS::Rosen::ModifierNG88} // namespace OHOS::Rosen::ModifierNG
Mrosen/modules/render_service_client/core/modifier_ng/appearance/rs_outline_modifier.h+2-0
@@ -36,6 +36,7 @@ public:
36 void SetOutlineDashWidth(const Vector4f& dashWidth);36 void SetOutlineDashWidth(const Vector4f& dashWidth);
37 void SetOutlineDashGap(const Vector4f& dashGap);37 void SetOutlineDashGap(const Vector4f& dashGap);
38 void SetOutlineRadius(const Vector4f& radius);38 void SetOutlineRadius(const Vector4f& radius);
39+ void SetOutlineSDFShader(const std::shared_ptr<RSNGShaderBase>& shader);
39 40 
40 const Vector4<Color> GetOutlineColor() const;41 const Vector4<Color> GetOutlineColor() const;
41 const Vector4f GetOutlineWidth() const;42 const Vector4f GetOutlineWidth() const;
@@ -43,6 +44,7 @@ public:
43 const Vector4f GetOutlineDashWidth() const;44 const Vector4f GetOutlineDashWidth() const;
44 const Vector4f GetOutlineDashGap() const;45 const Vector4f GetOutlineDashGap() const;
45 const Vector4f GetOutlineRadius() const;46 const Vector4f GetOutlineRadius() const;
47+ std::shared_ptr<RSNGShaderBase> GetOutlineSDFShader() const;
46};48};
47} // namespace OHOS::Rosen::ModifierNG49} // namespace OHOS::Rosen::ModifierNG
48#endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_NG_APPEARANCE_RS_OUTLINE_MODIFIER_H50#endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_NG_APPEARANCE_RS_OUTLINE_MODIFIER_H
Mrosen/modules/render_service_client/core/ui/rs_node.cpp+30-0
@@ -1822,6 +1822,21 @@ void RSNode::SetBorderDashGap(const Vector4f& dashGap)
1822 SetPropertyNG<ModifierNG::RSBorderModifier, &ModifierNG::RSBorderModifier::SetBorderDashGap>(dashGap);1822 SetPropertyNG<ModifierNG::RSBorderModifier, &ModifierNG::RSBorderModifier::SetBorderDashGap>(dashGap);
1823}1823}
1824 1824 
1825+void RSNode::SetBorderSDFShader(const std::shared_ptr<RSNGShaderBase>& shader)
1826+{
1827+ if (!shader) {
1828+ std::unique_lock<std::recursive_mutex> lock(propertyMutex_);
1829+ CHECK_FALSE_RETURN(CheckMultiThreadAccess(__func__));
1830+ auto modifier = GetModifierCreatedBySetter(ModifierNG::RSModifierType::BORDER);
1831+ if (modifier == nullptr || !modifier->HasProperty(ModifierNG::RSPropertyType::BORDER_SDF_SHADER)) {
1832+ return;
1833+ }
1834+ modifier->DetachProperty(ModifierNG::RSPropertyType::BORDER_SDF_SHADER);
1835+ return;
1836+ }
1837+ SetPropertyNG<ModifierNG::RSBorderModifier, &ModifierNG::RSBorderModifier::SetBorderSDFShader>(shader);
1838+}
1839+ 
1825void RSNode::SetOuterBorderColor(const Vector4<Color>& color)1840void RSNode::SetOuterBorderColor(const Vector4<Color>& color)
1826{1841{
1827 SetOutlineColor(color);1842 SetOutlineColor(color);
@@ -1874,6 +1889,21 @@ void RSNode::SetOutlineRadius(const Vector4f& radius)
1874 SetPropertyNG<ModifierNG::RSOutlineModifier, &ModifierNG::RSOutlineModifier::SetOutlineRadius>(radius);1889 SetPropertyNG<ModifierNG::RSOutlineModifier, &ModifierNG::RSOutlineModifier::SetOutlineRadius>(radius);
1875}1890}
1876 1891 
1892+void RSNode::SetOutlineSDFShader(const std::shared_ptr<RSNGShaderBase>& shader)
1893+{
1894+ if (!shader) {
1895+ std::unique_lock<std::recursive_mutex> lock(propertyMutex_);
1896+ CHECK_FALSE_RETURN(CheckMultiThreadAccess(__func__));
1897+ auto modifier = GetModifierCreatedBySetter(ModifierNG::RSModifierType::OUTLINE);
1898+ if (modifier == nullptr || !modifier->HasProperty(ModifierNG::RSPropertyType::OUTLINE_SDF_SHADER)) {
1899+ return;
1900+ }
1901+ modifier->DetachProperty(ModifierNG::RSPropertyType::OUTLINE_SDF_SHADER);
1902+ return;
1903+ }
1904+ SetPropertyNG<ModifierNG::RSOutlineModifier, &ModifierNG::RSOutlineModifier::SetOutlineSDFShader>(shader);
1905+}
1906+ 
1877bool RSNode::RegisterColorPickerCallback(uint64_t interval, ColorPickerCallback callback, uint32_t notifyThreshold)1907bool RSNode::RegisterColorPickerCallback(uint64_t interval, ColorPickerCallback callback, uint32_t notifyThreshold)
1878{1908{
1879 if (!callback) {1909 if (!callback) {
Mrosen/modules/render_service_client/core/ui/rs_node.h+14-0
@@ -1038,6 +1038,13 @@ public:
1038 */1038 */
1039 void SetBorderDashGap(const Vector4f& dashGap);1039 void SetBorderDashGap(const Vector4f& dashGap);
1040 1040 
1041+ /**
1042+ * @brief Sets the SDF border shader.
1043+ *
1044+ * @param shader Indicates the SDF border shader to be applied.
1045+ */
1046+ void SetBorderSDFShader(const std::shared_ptr<RSNGShaderBase>& shader);
1047+ 
1041 /**1048 /**
1042 * @brief Sets the color of the outer border.1049 * @brief Sets the color of the outer border.
1043 *1050 *
@@ -1108,6 +1115,13 @@ public:
1108 */1115 */
1109 void SetOutlineRadius(const Vector4f& radius);1116 void SetOutlineRadius(const Vector4f& radius);
1110 1117 
1118+ /**
1119+ * @brief Sets the SDF outline shader.
1120+ *
1121+ * @param shader Indicates the SDF outline shader to be applied.
1122+ */
1123+ void SetOutlineSDFShader(const std::shared_ptr<RSNGShaderBase>& shader);
1124+ 
1111 /**1125 /**
1112 * @brief Sets color picker params of the node.1126 * @brief Sets color picker params of the node.
1113 * @param placeholder The handle to receive realtime color.1127 * @param placeholder The handle to receive realtime color.
Mrosen/modules/render_service_client/core/ui_effect/property/src/rs_ui_shader_base.cpp+4-0
@@ -90,6 +90,10 @@ static std::unordered_map<RSNGEffectType, ShaderCreator> creatorLUT = {
90 return std::make_shared<RSNGDistortChroma>();90 return std::make_shared<RSNGDistortChroma>();
91 }91 }
92 },92 },
93+ {RSNGEffectType::BORDER_SDF_SHADER, [] {
94+ return std::make_shared<RSNGBorderSDFShader>();
95+ }
96+ },
93 {RSNGEffectType::SDF_EDGE_LIGHT_EFFECT, [] {97 {RSNGEffectType::SDF_EDGE_LIGHT_EFFECT, [] {
94 return std::make_shared<RSNGSDFEdgeLightEffect>();98 return std::make_shared<RSNGSDFEdgeLightEffect>();
95 }99 }
Mrosen/test/render_service/render_service_base/unittest/drawable/rs_property_drawable_foreground_test.cpp+147-0
@@ -17,6 +17,7 @@
17#include "drawable/rs_property_drawable_foreground.h"17#include "drawable/rs_property_drawable_foreground.h"
18#include "effect/rs_render_filter_base.h"18#include "effect/rs_render_filter_base.h"
19#include "effect/rs_render_shape_base.h"19#include "effect/rs_render_shape_base.h"
20+#include "effect/rs_render_shader_base.h"
20#include "ge_visual_effect_container.h"21#include "ge_visual_effect_container.h"
21#include "pipeline/rs_render_node.h"22#include "pipeline/rs_render_node.h"
22#include "render/rs_drawing_filter.h"23#include "render/rs_drawing_filter.h"
@@ -547,6 +548,152 @@ HWTEST_F(RSPropertyDrawableForegroundTest, RSParticleDrawableOnUpdateCacheTest00
547 EXPECT_FALSE(result);548 EXPECT_FALSE(result);
548}549}
549 550 
551+/**
552+ * @tc.name: DrawBorderWithSDFShader001
553+ * @tc.desc: Test DrawBorder with SDFShape and SDFShader set (SDF shader path)
554+ * @tc.type: FUNC
555+ * @tc.require:
556+ */
557+HWTEST_F(RSPropertyDrawableForegroundTest, DrawBorderWithSDFShader001, TestSize.Level1)
558+{
559+ NodeId id = 1;
560+ RSRenderNode node(id);
561+ 
562+ auto sdfShape = RSNGRenderShapeBase::Create(RSNGEffectType::SDF_RRECT_SHAPE);
563+ ASSERT_NE(sdfShape, nullptr);
564+ node.GetMutableRenderProperties().SetSDFShape(sdfShape);
565+ 
566+ auto sdfShader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
567+ ASSERT_NE(sdfShader, nullptr);
568+ 
569+ std::shared_ptr<RSBorder> border = std::make_shared<RSBorder>();
570+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
571+ border->widths_.emplace_back(2.0f);
572+ border->styles_.emplace_back(BorderStyle::SOLID);
573+ border->SetSDFShader(sdfShader);
574+ 
575+ std::shared_ptr<DrawableV2::RSBorderDrawable> borderDrawable =
576+ std::make_shared<DrawableV2::RSBorderDrawable>();
577+ Drawing::Canvas canvas;
578+ borderDrawable->DrawBorder(node.GetRenderProperties(), canvas, border, false);
579+}
580+ 
581+/**
582+ * @tc.name: DrawBorderWithSDFShaderAndOutline001
583+ * @tc.desc: Test DrawBorder SDF shader path with isOutline=true and zero radius
584+ * @tc.type: FUNC
585+ * @tc.require:
586+ */
587+HWTEST_F(RSPropertyDrawableForegroundTest, DrawBorderWithSDFShaderAndOutline001, TestSize.Level1)
588+{
589+ NodeId id = 1;
590+ RSRenderNode node(id);
591+ 
592+ auto sdfShape = RSNGRenderShapeBase::Create(RSNGEffectType::SDF_RRECT_SHAPE);
593+ ASSERT_NE(sdfShape, nullptr);
594+ node.GetMutableRenderProperties().SetSDFShape(sdfShape);
595+ 
596+ auto sdfShader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
597+ ASSERT_NE(sdfShader, nullptr);
598+ 
599+ std::shared_ptr<RSBorder> border = std::make_shared<RSBorder>();
600+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
601+ border->widths_.emplace_back(2.0f);
602+ border->styles_.emplace_back(BorderStyle::SOLID);
603+ border->SetSDFShader(sdfShader);
604+ border->SetRadiusFour({0.f, 0.f, 0.f, 0.f});
605+ 
606+ std::shared_ptr<DrawableV2::RSBorderDrawable> borderDrawable =
607+ std::make_shared<DrawableV2::RSBorderDrawable>();
608+ Drawing::Canvas canvas;
609+ borderDrawable->DrawBorder(node.GetRenderProperties(), canvas, border, true);
610+}
611+ 
612+/**
613+ * @tc.name: DrawBorderWithSDFShaderNonZeroRadius001
614+ * @tc.desc: Test DrawBorder SDF shader path with isOutline=true and non-zero radius
615+ * @tc.type: FUNC
616+ * @tc.require:
617+ */
618+HWTEST_F(RSPropertyDrawableForegroundTest, DrawBorderWithSDFShaderNonZeroRadius001, TestSize.Level1)
619+{
620+ NodeId id = 1;
621+ RSRenderNode node(id);
622+ 
623+ auto sdfShape = RSNGRenderShapeBase::Create(RSNGEffectType::SDF_RRECT_SHAPE);
624+ ASSERT_NE(sdfShape, nullptr);
625+ node.GetMutableRenderProperties().SetSDFShape(sdfShape);
626+ 
627+ auto sdfShader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
628+ ASSERT_NE(sdfShader, nullptr);
629+ 
630+ std::shared_ptr<RSBorder> border = std::make_shared<RSBorder>();
631+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
632+ border->widths_.emplace_back(2.0f);
633+ border->styles_.emplace_back(BorderStyle::SOLID);
634+ border->SetSDFShader(sdfShader);
635+ border->SetRadiusFour({10.f, 10.f, 10.f, 10.f});
636+ 
637+ std::shared_ptr<DrawableV2::RSBorderDrawable> borderDrawable =
638+ std::make_shared<DrawableV2::RSBorderDrawable>();
639+ Drawing::Canvas canvas;
640+ borderDrawable->DrawBorder(node.GetRenderProperties(), canvas, border, true);
641+}
642+ 
643+/**
644+ * @tc.name: DrawBorderNoSDFShape001
645+ * @tc.desc: Test DrawBorder without SDFShape does not enter SDF shader path
646+ * @tc.type: FUNC
647+ * @tc.require:
648+ */
649+HWTEST_F(RSPropertyDrawableForegroundTest, DrawBorderNoSDFShape001, TestSize.Level1)
650+{
651+ RSProperties properties;
652+ std::shared_ptr<RSBorder> border = std::make_shared<RSBorder>();
653+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
654+ border->widths_.emplace_back(2.0f);
655+ border->styles_.emplace_back(BorderStyle::SOLID);
656+ 
657+ auto sdfShader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
658+ ASSERT_NE(sdfShader, nullptr);
659+ border->SetSDFShader(sdfShader);
660+ 
661+ std::shared_ptr<DrawableV2::RSBorderDrawable> borderDrawable =
662+ std::make_shared<DrawableV2::RSBorderDrawable>();
663+ Drawing::Canvas canvas;
664+ borderDrawable->DrawBorder(properties, canvas, border, false);
665+}
666+ 
667+/**
668+ * @tc.name: DrawBorderNoSDFShader001
669+ * @tc.desc: Test DrawBorder without SDFShader does not enter SDF shader path
670+ * @tc.type: FUNC
671+ * @tc.require:
672+ */
673+HWTEST_F(RSPropertyDrawableForegroundTest, DrawBorderNoSDFShader001, TestSize.Level1)
674+{
675+ NodeId id = 1;
676+ RSRenderNode node(id);
677+ 
678+ auto sdfShape = RSNGRenderShapeBase::Create(RSNGEffectType::SDF_RRECT_SHAPE);
679+ ASSERT_NE(sdfShape, nullptr);
680+ node.GetMutableRenderProperties().SetSDFShape(sdfShape);
681+ 
682+ std::shared_ptr<RSBorder> border = std::make_shared<RSBorder>();
683+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
684+ border->widths_.emplace_back(2.0f);
685+ border->styles_.emplace_back(BorderStyle::SOLID);
686+ 
687+ auto sdfShader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
688+ ASSERT_NE(sdfShader, nullptr);
689+ border->SetSDFShader(sdfShader);
690+ 
691+ std::shared_ptr<DrawableV2::RSBorderDrawable> borderDrawable =
692+ std::make_shared<DrawableV2::RSBorderDrawable>();
693+ Drawing::Canvas canvas;
694+ borderDrawable->DrawBorder(node.GetRenderProperties(), canvas, border, false);
695+}
696+ 
550/**697/**
551 * @tc.name: RSForegroundFilterRestoreDrawableDrawRectTest001698 * @tc.name: RSForegroundFilterRestoreDrawableDrawRectTest001
552 * @tc.desc: Test RSForegroundFilterRestoreDrawable::OnUpdate with custom draw rect699 * @tc.desc: Test RSForegroundFilterRestoreDrawable::OnUpdate with custom draw rect
Mrosen/test/render_service/render_service_base/unittest/effect/rs_render_shader_base_test.cpp+12-0
@@ -425,4 +425,16 @@ HWTEST_F(RSNGRenderShaderBaseTest, CalcRect006, TestSize.Level1)
425 RectF result = RSNGRenderShaderHelper::CalcRect(shader, bound);425 RectF result = RSNGRenderShaderHelper::CalcRect(shader, bound);
426 EXPECT_TRUE(result == bound);426 EXPECT_TRUE(result == bound);
427}427}
428+ 
429+/**
430+ * @tc.name: CreateBorderSDFShader001
431+ * @tc.desc: Verify that Create returns a non-null instance for BORDER_SDF_SHADER type
432+ * @tc.type: FUNC
433+ */
434+HWTEST_F(RSNGRenderShaderBaseTest, CreateBorderSDFShader001, TestSize.Level1)
435+{
436+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
437+ EXPECT_NE(shader, nullptr);
438+ EXPECT_EQ(shader->GetType(), RSNGEffectType::BORDER_SDF_SHADER);
439+}
428} // namespace OHOS::Rosen440} // namespace OHOS::Rosen
Mrosen/test/render_service/render_service_base/unittest/property/rs_properties_test.cpp+88-0
@@ -3945,6 +3945,94 @@ HWTEST_F(RSPropertiesTest, SetOverlayNGShader002, TestSize.Level1)
3945 EXPECT_EQ(properties.GetOverlayNGShader(), overlayShader);3945 EXPECT_EQ(properties.GetOverlayNGShader(), overlayShader);
3946}3946}
3947 3947 
3948+/**
3949+ * @tc.name: SetAndGetBorderSDFShader001
3950+ * @tc.desc: Test SetBorderSDFShader lazy-creates border_ and GetBorderSDFShader returns shader
3951+ * @tc.type: FUNC
3952+ */
3953+HWTEST_F(RSPropertiesTest, SetAndGetBorderSDFShader001, TestSize.Level1)
3954+{
3955+ RSProperties properties;
3956+ EXPECT_EQ(properties.GetBorderSDFShader(), nullptr);
3957+ 
3958+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
3959+ ASSERT_NE(shader, nullptr);
3960+ properties.SetBorderSDFShader(shader);
3961+ EXPECT_EQ(properties.GetBorderSDFShader(), shader);
3962+ EXPECT_NE(properties.border_, nullptr);
3963+}
3964+ 
3965+/**
3966+ * @tc.name: SetBorderSDFShaderWithExistingBorder001
3967+ * @tc.desc: Test SetBorderSDFShader when border_ already exists
3968+ * @tc.type: FUNC
3969+ */
3970+HWTEST_F(RSPropertiesTest, SetBorderSDFShaderWithExistingBorder001, TestSize.Level1)
3971+{
3972+ RSProperties properties;
3973+ properties.border_ = std::make_shared<RSBorder>();
3974+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
3975+ ASSERT_NE(shader, nullptr);
3976+ properties.SetBorderSDFShader(shader);
3977+ EXPECT_EQ(properties.GetBorderSDFShader(), shader);
3978+}
3979+ 
3980+/**
3981+ * @tc.name: GetBorderSDFShaderNullBorder001
3982+ * @tc.desc: Test GetBorderSDFShader returns nullptr when border_ is null
3983+ * @tc.type: FUNC
3984+ */
3985+HWTEST_F(RSPropertiesTest, GetBorderSDFShaderNullBorder001, TestSize.Level1)
3986+{
3987+ RSProperties properties;
3988+ EXPECT_EQ(properties.border_, nullptr);
3989+ EXPECT_EQ(properties.GetBorderSDFShader(), nullptr);
3990+}
3991+ 
3992+/**
3993+ * @tc.name: SetAndGetOutlineSDFShader001
3994+ * @tc.desc: Test SetOutlineSDFShader lazy-creates outline_ and GetOutlineSDFShader returns shader
3995+ * @tc.type: FUNC
3996+ */
3997+HWTEST_F(RSPropertiesTest, SetAndGetOutlineSDFShader001, TestSize.Level1)
3998+{
3999+ RSProperties properties;
4000+ EXPECT_EQ(properties.GetOutlineSDFShader(), nullptr);
4001+ 
4002+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
4003+ ASSERT_NE(shader, nullptr);
4004+ properties.SetOutlineSDFShader(shader);
4005+ EXPECT_EQ(properties.GetOutlineSDFShader(), shader);
4006+ EXPECT_NE(properties.outline_, nullptr);
4007+}
4008+ 
4009+/**
4010+ * @tc.name: SetOutlineSDFShaderWithExistingOutline001
4011+ * @tc.desc: Test SetOutlineSDFShader when outline_ already exists
4012+ * @tc.type: FUNC
4013+ */
4014+HWTEST_F(RSPropertiesTest, SetOutlineSDFShaderWithExistingOutline001, TestSize.Level1)
4015+{
4016+ RSProperties properties;
4017+ properties.outline_ = std::make_shared<RSBorder>(true);
4018+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
4019+ ASSERT_NE(shader, nullptr);
4020+ properties.SetOutlineSDFShader(shader);
4021+ EXPECT_EQ(properties.GetOutlineSDFShader(), shader);
4022+}
4023+ 
4024+/**
4025+ * @tc.name: GetOutlineSDFShaderNullOutline001
4026+ * @tc.desc: Test GetOutlineSDFShader returns nullptr when outline_ is null
4027+ * @tc.type: FUNC
4028+ */
4029+HWTEST_F(RSPropertiesTest, GetOutlineSDFShaderNullOutline001, TestSize.Level1)
4030+{
4031+ RSProperties properties;
4032+ EXPECT_EQ(properties.outline_, nullptr);
4033+ EXPECT_EQ(properties.GetOutlineSDFShader(), nullptr);
4034+}
4035+ 
3948/**4036/**
3949 * @tc.name: GetMaterialShader0014037 * @tc.name: GetMaterialShader001
3950 * @tc.desc: test GetMaterialShader when effect_ is nullptr4038 * @tc.desc: test GetMaterialShader when effect_ is nullptr
Mrosen/test/render_service/render_service_base/unittest/render/rs_border_test.cpp+62-0
@@ -15,6 +15,7 @@
15 15 
16#include "gtest/gtest.h"16#include "gtest/gtest.h"
17#include "include/render/rs_border.h"17#include "include/render/rs_border.h"
18+#include "effect/rs_render_shader_base.h"
18 19 
19#include "property/rs_properties.h"20#include "property/rs_properties.h"
20#include "property/rs_properties_painter.h"21#include "property/rs_properties_painter.h"
@@ -1484,4 +1485,65 @@ HWTEST_F(RSBorderTest, DrawLeftBorderTest, TestSize.Level1)
1484 border->DrawLeftBorder(canvas, pen, borderGeo);1485 border->DrawLeftBorder(canvas, pen, borderGeo);
1485 EXPECT_FALSE(border->styles_.empty());1486 EXPECT_FALSE(border->styles_.empty());
1486}1487}
1488+ 
1489+/**
1490+ * @tc.name: SetAndGetSDFShader001
1491+ * @tc.desc: Test SetSDFShader and GetSDFShader with valid shader
1492+ * @tc.type: FUNC
1493+ */
1494+HWTEST_F(RSBorderTest, SetAndGetSDFShader001, TestSize.Level1)
1495+{
1496+ auto border = std::make_shared<RSBorder>();
1497+ EXPECT_EQ(border->GetSDFShader(), nullptr);
1498+ 
1499+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
1500+ ASSERT_NE(shader, nullptr);
1501+ border->SetSDFShader(shader);
1502+ EXPECT_EQ(border->GetSDFShader(), shader);
1503+ 
1504+ border->SetSDFShader(nullptr);
1505+ EXPECT_EQ(border->GetSDFShader(), nullptr);
1506+}
1507+ 
1508+/**
1509+ * @tc.name: HasBorderWithSDFShader001
1510+ * @tc.desc: Test HasBorder returns true when sdfShader_ is set (early return branch)
1511+ * @tc.type: FUNC
1512+ */
1513+HWTEST_F(RSBorderTest, HasBorderWithSDFShader001, TestSize.Level1)
1514+{
1515+ auto border = std::make_shared<RSBorder>();
1516+ EXPECT_FALSE(border->HasBorder());
1517+ 
1518+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
1519+ ASSERT_NE(shader, nullptr);
1520+ border->SetSDFShader(shader);
1521+ EXPECT_TRUE(border->HasBorder());
1522+ 
1523+ border->SetSDFShader(nullptr);
1524+ EXPECT_FALSE(border->HasBorder());
1525+ 
1526+ border->colors_.emplace_back(Color(0xFF, 0xFF, 0xFF, 0xFF));
1527+ border->widths_.emplace_back(1.0f);
1528+ border->styles_.emplace_back(BorderStyle::SOLID);
1529+ EXPECT_TRUE(border->HasBorder());
1530+}
1531+ 
1532+/**
1533+ * @tc.name: ToStringWithSDFShader001
1534+ * @tc.desc: Test ToString includes sdfShader dump when sdfShader_ is set
1535+ * @tc.type: FUNC
1536+ */
1537+HWTEST_F(RSBorderTest, ToStringWithSDFShader001, TestSize.Level1)
1538+{
1539+ auto border = std::make_shared<RSBorder>();
1540+ std::string strNoShader = border->ToString();
1541+ EXPECT_EQ(strNoShader.find("sdfShader"), std::string::npos);
1542+ 
1543+ auto shader = RSNGRenderShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
1544+ ASSERT_NE(shader, nullptr);
1545+ border->SetSDFShader(shader);
1546+ std::string strWithShader = border->ToString();
1547+ EXPECT_NE(strWithShader.find("sdfShader"), std::string::npos);
1548+}
1487} // namespace OHOS::Rosen1549} // namespace OHOS::Rosen
Mrosen/test/render_service/render_service_client/unittest/modifier_ng/appearance/rs_border_modifier_test.cpp+17-0
@@ -24,6 +24,7 @@
24 24 
25#include "common/rs_vector4.h"25#include "common/rs_vector4.h"
26#include "modifier_ng/appearance/rs_border_modifier.h"26#include "modifier_ng/appearance/rs_border_modifier.h"
27+#include "ui_effect/property/include/rs_ui_shader_base.h"
27 28 
28using namespace testing;29using namespace testing;
29using namespace testing::ext;30using namespace testing::ext;
@@ -71,4 +72,20 @@ HWTEST_F(RSBorderModifierNGTypeTest, RSBorderModifierTest, TestSize.Level1)
71 modifier->SetBorderDashGap(dashGap);72 modifier->SetBorderDashGap(dashGap);
72 EXPECT_EQ(modifier->GetBorderDashGap(), dashGap);73 EXPECT_EQ(modifier->GetBorderDashGap(), dashGap);
73}74}
75+ 
76+/**
77+ * @tc.name: RSBorderModifierSetGetBorderSDFShader
78+ * @tc.desc: Test SetBorderSDFShader and GetBorderSDFShader
79+ * @tc.type: FUNC
80+ */
81+HWTEST_F(RSBorderModifierNGTypeTest, RSBorderModifierSetGetBorderSDFShader, TestSize.Level1)
82+{
83+ std::shared_ptr<ModifierNG::RSBorderModifier> modifier = std::make_shared<ModifierNG::RSBorderModifier>();
84+ EXPECT_EQ(modifier->GetBorderSDFShader(), nullptr);
85+ 
86+ auto shader = RSNGShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
87+ ASSERT_NE(shader, nullptr);
88+ modifier->SetBorderSDFShader(shader);
89+ EXPECT_EQ(modifier->GetBorderSDFShader(), shader);
90+}
74} // namespace OHOS::Rosen91} // namespace OHOS::Rosen
Mrosen/test/render_service/render_service_client/unittest/modifier_ng/appearance/rs_outline_modifier_test.cpp+17-0
@@ -24,6 +24,7 @@
24 24 
25#include "common/rs_vector4.h"25#include "common/rs_vector4.h"
26#include "modifier_ng/appearance/rs_outline_modifier.h"26#include "modifier_ng/appearance/rs_outline_modifier.h"
27+#include "ui_effect/property/include/rs_ui_shader_base.h"
27 28 
28using namespace testing;29using namespace testing;
29using namespace testing::ext;30using namespace testing::ext;
@@ -73,4 +74,20 @@ HWTEST_F(RSOutlineModifierNGTypeTest, RSOutlineModifierTest, TestSize.Level1)
73 modifier->SetOutlineRadius(radius);74 modifier->SetOutlineRadius(radius);
74 EXPECT_EQ(modifier->GetOutlineRadius(), radius);75 EXPECT_EQ(modifier->GetOutlineRadius(), radius);
75}76}
77+ 
78+/**
79+ * @tc.name: RSOutlineModifierSetGetOutlineSDFShader
80+ * @tc.desc: Test SetOutlineSDFShader and GetOutlineSDFShader
81+ * @tc.type: FUNC
82+ */
83+HWTEST_F(RSOutlineModifierNGTypeTest, RSOutlineModifierSetGetOutlineSDFShader, TestSize.Level1)
84+{
85+ std::shared_ptr<ModifierNG::RSOutlineModifier> modifier = std::make_shared<ModifierNG::RSOutlineModifier>();
86+ EXPECT_EQ(modifier->GetOutlineSDFShader(), nullptr);
87+ 
88+ auto shader = RSNGShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
89+ ASSERT_NE(shader, nullptr);
90+ modifier->SetOutlineSDFShader(shader);
91+ EXPECT_EQ(modifier->GetOutlineSDFShader(), shader);
92+}
76} // namespace OHOS::Rosen93} // namespace OHOS::Rosen
Mrosen/test/render_service/render_service_client/unittest/property/rs_ui_shader_base_test.cpp+13-0
@@ -98,4 +98,17 @@ HWTEST_F(RSUIShaderBaseTest, RSNGShaderBaseCreateAIBarRectHalo, TestSize.Level1)
98 EXPECT_NE(shader, nullptr);98 EXPECT_NE(shader, nullptr);
99 EXPECT_EQ(shader->GetType(), RSNGEffectType::AIBAR_RECT_HALO);99 EXPECT_EQ(shader->GetType(), RSNGEffectType::AIBAR_RECT_HALO);
100}100}
101+ 
102+/**
103+ * @tc.name: RSNGShaderBaseCreateBorderSDFShader
104+ * @tc.desc: Calling Create(RSNGEffectType::BORDER_SDF_SHADER)
105+ * should return a non-null RSNGBorderSDFShader instance
106+ * @tc.type:FUNC
107+ */
108+HWTEST_F(RSUIShaderBaseTest, RSNGShaderBaseCreateBorderSDFShader, TestSize.Level1)
109+{
110+ auto shader = RSNGShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
111+ EXPECT_NE(shader, nullptr);
112+ EXPECT_EQ(shader->GetType(), RSNGEffectType::BORDER_SDF_SHADER);
113+}
101} // namespace OHOS::Rosen114} // namespace OHOS::Rosen
Mrosen/test/render_service/render_service_client/unittest/ui/rs_node_test_2.cpp+42-0
@@ -1242,4 +1242,46 @@ HWTEST_F(RSNodeTest2, ReSortChildrenByZIndexTest, TestSize.Level1)
1242 ASSERT_NE(transaction, nullptr);1242 ASSERT_NE(transaction, nullptr);
1243 ASSERT_FALSE(transaction->IsEmpty());1243 ASSERT_FALSE(transaction->IsEmpty());
1244}1244}
1245+ 
1246+/**
1247+ * @tc.name: SetBorderSDFShader001
1248+ * @tc.desc: test results of SetBorderSDFShader
1249+ * @tc.type: FUNC
1250+ */
1251+HWTEST_F(RSNodeTest2, SetBorderSDFShader001, TestSize.Level1)
1252+{
1253+ auto rsNode = RSCanvasNode::Create();
1254+ rsNode->SetBorderSDFShader(nullptr);
1255+ ASSERT_EQ(rsNode->GetModifierByType(ModifierNG::RSModifierType::BORDER), nullptr);
1256+ 
1257+ auto shader = RSNGShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
1258+ rsNode->SetBorderSDFShader(shader);
1259+ ASSERT_NE(rsNode->GetModifierByType(ModifierNG::RSModifierType::BORDER), nullptr);
1260+ 
1261+ rsNode->SetBorderSDFShader(nullptr);
1262+ auto modifier = rsNode->GetModifierByType(ModifierNG::RSModifierType::BORDER);
1263+ ASSERT_NE(modifier, nullptr);
1264+ ASSERT_EQ(modifier->properties_.find(ModifierNG::RSPropertyType::BORDER_SDF_SHADER), modifier->properties_.end());
1265+}
1266+ 
1267+/**
1268+ * @tc.name: SetOutlineSDFShader001
1269+ * @tc.desc: test results of SetOutlineSDFShader
1270+ * @tc.type: FUNC
1271+ */
1272+HWTEST_F(RSNodeTest2, SetOutlineSDFShader001, TestSize.Level1)
1273+{
1274+ auto rsNode = RSCanvasNode::Create();
1275+ rsNode->SetOutlineSDFShader(nullptr);
1276+ ASSERT_EQ(rsNode->GetModifierByType(ModifierNG::RSModifierType::OUTLINE), nullptr);
1277+ 
1278+ auto shader = RSNGShaderBase::Create(RSNGEffectType::BORDER_SDF_SHADER);
1279+ rsNode->SetOutlineSDFShader(shader);
1280+ ASSERT_NE(rsNode->GetModifierByType(ModifierNG::RSModifierType::OUTLINE), nullptr);
1281+ 
1282+ rsNode->SetOutlineSDFShader(nullptr);
1283+ auto modifier = rsNode->GetModifierByType(ModifierNG::RSModifierType::OUTLINE);
1284+ ASSERT_NE(modifier, nullptr);
1285+ ASSERT_EQ(modifier->properties_.find(ModifierNG::RSPropertyType::OUTLINE_SDF_SHADER), modifier->properties_.end());
1286+}
1245} // namespace OHOS::Rosen1287} // namespace OHOS::Rosen