1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "effect/rs_render_shader_base.h"
17
18 #include <unordered_map>
19
20 #include "effect/rs_render_mask_base.h"
21 #include "ge_visual_effect.h"
22 #include "ge_visual_effect_container.h"
23 #include "platform/common/rs_log.h"
24 #include "render/rs_effect_luminance_manager.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 using ShaderCreator = std::function<std::shared_ptr<RSNGRenderShaderBase>()>;
29
30 static std::unordered_map<RSNGEffectType, ShaderCreator> creatorLUT = {
__anon0310e90f0102null31 {RSNGEffectType::CONTOUR_DIAGONAL_FLOW_LIGHT, [] {
32 return std::make_shared<RSNGRenderContourDiagonalFlowLight>();
33 }
34 },
__anon0310e90f0202null35 {RSNGEffectType::WAVY_RIPPLE_LIGHT, [] {
36 return std::make_shared<RSNGRenderWavyRippleLight>();
37 }
38 },
__anon0310e90f0302null39 {RSNGEffectType::AURORA_NOISE, [] {
40 return std::make_shared<RSNGRenderAuroraNoise>();
41 }
42 },
__anon0310e90f0402null43 {RSNGEffectType::PARTICLE_CIRCULAR_HALO, [] {
44 return std::make_shared<RSNGRenderParticleCircularHalo>();
45 }
46 },
__anon0310e90f0502null47 {RSNGEffectType::COLOR_GRADIENT_EFFECT, [] {
48 return std::make_shared<RSNGRenderColorGradientEffect>();
49 }
50 },
__anon0310e90f0602null51 {RSNGEffectType::LIGHT_CAVE, [] {
52 return std::make_shared<RSNGRenderLightCave>();
53 }
54 },
__anon0310e90f0702null55 {RSNGEffectType::BORDER_LIGHT, [] {
56 return std::make_shared<RSNGRenderBorderLight>();
57 }
58 }
59 };
60
Create(RSNGEffectType type)61 std::shared_ptr<RSNGRenderShaderBase> RSNGRenderShaderBase::Create(RSNGEffectType type)
62 {
63 auto it = creatorLUT.find(type);
64 return it != creatorLUT.end() ? it->second() : nullptr;
65 }
66
Unmarshalling(Parcel & parcel,std::shared_ptr<RSNGRenderShaderBase> & val)67 [[nodiscard]] bool RSNGRenderShaderBase::Unmarshalling(Parcel& parcel, std::shared_ptr<RSNGRenderShaderBase>& val)
68 {
69 std::shared_ptr<RSNGRenderShaderBase> head = nullptr;
70 auto current = head;
71 for (size_t shaderCount = 0; shaderCount <= EFFECT_COUNT_LIMIT; ++shaderCount) {
72 RSNGEffectTypeUnderlying type = 0;
73 if (!RSMarshallingHelper::Unmarshalling(parcel, type)) {
74 ROSEN_LOGE("RSNGRenderShaderBase: Unmarshalling type failed");
75 return false;
76 }
77
78 if (type == END_OF_CHAIN) {
79 val = head;
80 return true;
81 }
82
83 auto shader = Create(static_cast<RSNGEffectType>(type));
84 if (shader && !shader->OnUnmarshalling(parcel)) {
85 ROSEN_LOGE("RSNGRenderShaderBase: Unmarshalling shader failed with type %{public}d", type);
86 return false;
87 }
88 if (!current) {
89 head = shader; // init head
90 } else {
91 current->nextEffect_ = shader;
92 }
93 current = shader;
94 }
95
96 ROSEN_LOGE("RSNGRenderShaderBase: Unmarshalling shader count arrive limit(%{public}zu)",
97 EFFECT_COUNT_LIMIT);
98 return false;
99 }
100
Dump(std::string & out) const101 void RSNGRenderShaderBase::Dump(std::string& out) const
102 {
103 std::string descStr = ": ";
104 std::string splitStr = ", ";
105
106 out += RSNGRenderEffectHelper::GetEffectTypeString(GetType());
107 out += descStr;
108 DumpProperties(out);
109 if (nextEffect_) {
110 out += splitStr;
111 nextEffect_->Dump(out);
112 }
113 }
114
CheckEnableEDR(std::shared_ptr<RSNGRenderShaderBase> shader)115 bool RSNGRenderShaderHelper::CheckEnableEDR(std::shared_ptr<RSNGRenderShaderBase> shader)
116 {
117 auto current = shader;
118 while (current) {
119 if (RSEffectLuminanceManager::GetEnableHdrEffect(current)) {
120 return true;
121 }
122 current = current->nextEffect_;
123 }
124 return false;
125 }
126
SetRotationAngle(std::shared_ptr<RSNGRenderShaderBase> shader,const Vector3f & rotationAngle)127 void RSNGRenderShaderHelper::SetRotationAngle(std::shared_ptr<RSNGRenderShaderBase> shader,
128 const Vector3f& rotationAngle)
129 {
130 auto current = shader;
131 while (current) {
132 if (current->GetType() == RSNGEffectType::BORDER_LIGHT) {
133 auto borderLightShader = std::static_pointer_cast<RSNGRenderBorderLight>(current);
134 borderLightShader->Setter<BorderLightRotationAngleRenderTag>(rotationAngle);
135 }
136 current = current->nextEffect_;
137 }
138 }
139
SetCornerRadius(std::shared_ptr<RSNGRenderShaderBase> shader,float cornerRadius)140 void RSNGRenderShaderHelper::SetCornerRadius(std::shared_ptr<RSNGRenderShaderBase> shader,
141 float cornerRadius)
142 {
143 auto current = shader;
144 while (current) {
145 if (current->GetType() == RSNGEffectType::BORDER_LIGHT) {
146 auto borderLightShader = std::static_pointer_cast<RSNGRenderBorderLight>(current);
147 borderLightShader->Setter<BorderLightCornerRadiusRenderTag>(cornerRadius);
148 }
149 current = current->nextEffect_;
150 }
151 }
152 } // namespace Rosen
153 } // namespace OHOS
154