• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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/shader_effect.h"
17 #include "effect/shader_effect_lazy.h"
18 #include "utils/log.h"
19 
20 #include "impl_factory.h"
21 
22 #ifdef ROSEN_OHOS
23 #include "utils/object_helper.h"
24 #endif
25 
26 namespace OHOS {
27 namespace Rosen {
28 namespace Drawing {
29 /* ColorShader */
ShaderEffect(ShaderEffectType t,ColorQuad color)30 ShaderEffect::ShaderEffect(ShaderEffectType t, ColorQuad color) noexcept : ShaderEffect(t)
31 {
32     impl_->InitWithColor(color);
33 }
34 
35 /* ColorShader With ColorSpace */
ShaderEffect(ShaderEffectType t,const Color4f & color,std::shared_ptr<ColorSpace> colorSpace)36 ShaderEffect::ShaderEffect(ShaderEffectType t, const Color4f& color, std::shared_ptr<ColorSpace> colorSpace) noexcept
37     : ShaderEffect(t)
38 {
39     impl_->InitWithColorSpace(color, colorSpace);
40 }
41 
42 /* BlendShader */
ShaderEffect(ShaderEffectType t,ShaderEffect & dst,ShaderEffect & src,BlendMode mode)43 ShaderEffect::ShaderEffect(ShaderEffectType t, ShaderEffect& dst, ShaderEffect& src, BlendMode mode) noexcept
44     : ShaderEffect(t)
45 {
46     impl_->InitWithBlend(dst, src, mode);
47 }
48 
49 /* ImageShader */
ShaderEffect(ShaderEffectType t,const Image & image,TileMode tileX,TileMode tileY,const SamplingOptions & sampling,const Matrix & matrix)50 ShaderEffect::ShaderEffect(ShaderEffectType t, const Image& image, TileMode tileX, TileMode tileY,
51     const SamplingOptions& sampling, const Matrix& matrix) noexcept
52     : ShaderEffect(t)
53 {
54     impl_->InitWithImage(image, tileX, tileY, sampling, matrix);
55 }
56 
57 /* PictureShader */
ShaderEffect(ShaderEffectType t,const Picture & picture,TileMode tileX,TileMode tileY,FilterMode mode,const Matrix & matrix,const Rect & rect)58 ShaderEffect::ShaderEffect(ShaderEffectType t, const Picture& picture, TileMode tileX, TileMode tileY, FilterMode mode,
59     const Matrix& matrix, const Rect& rect) noexcept
60     : ShaderEffect(t)
61 {
62     impl_->InitWithPicture(picture, tileX, tileY, mode, matrix, rect);
63 }
64 
65 /* LinearGradient */
ShaderEffect(ShaderEffectType t,const Point & startPt,const Point & endPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)66 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& startPt, const Point& endPt,
67     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode, const Matrix *matrix) noexcept
68     : ShaderEffect(t)
69 {
70     impl_->InitWithLinearGradient(startPt, endPt, colors, pos, mode, matrix);
71 }
72 
73 /* LinearGradient */
ShaderEffect(ShaderEffectType t,const Point & startPt,const Point & endPt,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)74 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& startPt, const Point& endPt,
75     const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace, const std::vector<scalar>& pos,
76     TileMode mode, const Matrix *matrix) noexcept
77     : ShaderEffect(t)
78 {
79     impl_->InitWithLinearGradient(startPt, endPt, colors, colorSpace, pos, mode, matrix);
80 }
81 
82 /* RadialGradient */
ShaderEffect(ShaderEffectType t,const Point & centerPt,scalar radius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)83 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& centerPt, scalar radius,
84     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode, const Matrix *matrix) noexcept
85     : ShaderEffect(t)
86 {
87     impl_->InitWithRadialGradient(centerPt, radius, colors, pos, mode, matrix);
88 }
89 
90 /* RadialGradient */
ShaderEffect(ShaderEffectType t,const Point & centerPt,scalar radius,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)91 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& centerPt, scalar radius,
92     const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace, const std::vector<scalar>& pos,
93     TileMode mode, const Matrix* matrix) noexcept
94     : ShaderEffect(t)
95 {
96     impl_->InitWithRadialGradient(centerPt, radius, colors, colorSpace, pos, mode, matrix);
97 }
98 
99 /* TwoPointConicalGradient */
ShaderEffect(ShaderEffectType t,const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)100 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& startPt, scalar startRadius, const Point& endPt,
101     scalar endRadius, const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode,
102     const Matrix *matrix) noexcept
103     : ShaderEffect(t)
104 {
105     impl_->InitWithTwoPointConical(startPt, startRadius, endPt, endRadius, colors, pos, mode, matrix);
106 }
107 
108 /* TwoPointConicalGradient */
ShaderEffect(ShaderEffectType t,const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)109 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& startPt, scalar startRadius, const Point& endPt,
110     scalar endRadius, const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace,
111     const std::vector<scalar>& pos, TileMode mode, const Matrix* matrix) noexcept
112     : ShaderEffect(t)
113 {
114     impl_->InitWithTwoPointConical(startPt, startRadius, endPt, endRadius, colors, colorSpace, pos, mode, matrix);
115 }
116 
117 /* SweepGradient */
ShaderEffect(ShaderEffectType t,const Point & centerPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,scalar startAngle,scalar endAngle,const Matrix * matrix)118 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& centerPt, const std::vector<ColorQuad>& colors,
119     const std::vector<scalar>& pos, TileMode mode, scalar startAngle, scalar endAngle, const Matrix *matrix) noexcept
120     : ShaderEffect(t)
121 {
122     impl_->InitWithSweepGradient(centerPt, colors, pos, mode, startAngle, endAngle, matrix);
123 }
124 
125 /* SweepGradient */
ShaderEffect(ShaderEffectType t,const Point & centerPt,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,scalar startAngle,scalar endAngle,const Matrix * matrix)126 ShaderEffect::ShaderEffect(ShaderEffectType t, const Point& centerPt, const std::vector<Color4f>& colors,
127     std::shared_ptr<ColorSpace> colorSpace, const std::vector<scalar>& pos, TileMode mode, scalar startAngle,
128     scalar endAngle, const Matrix* matrix) noexcept
129     : ShaderEffect(t)
130 {
131     impl_->InitWithSweepGradient(centerPt, colors, colorSpace, pos, mode, startAngle, endAngle, matrix);
132 }
133 
134 /* ExtendShader */
ShaderEffect(ShaderEffectType t,std::shared_ptr<ExtendObject> object)135 ShaderEffect::ShaderEffect(ShaderEffectType t, std::shared_ptr<ExtendObject> object) noexcept
136     : type_(t), impl_(ImplFactory::CreateShaderEffectImpl()), object_(object) {}
137 
138 /* SdfShader */
ShaderEffect(ShaderEffectType t,const SDFShapeBase & shape)139 ShaderEffect::ShaderEffect(ShaderEffectType t, const SDFShapeBase& shape) noexcept
140     : ShaderEffect(t)
141 {
142     impl_->InitWithSdf(shape);
143 }
144 
ShaderEffect()145 ShaderEffect::ShaderEffect() noexcept
146     : type_(ShaderEffect::ShaderEffectType::NO_TYPE), impl_(ImplFactory::CreateShaderEffectImpl())
147 {}
148 
ShaderEffect(ShaderEffectType t)149 ShaderEffect::ShaderEffect(ShaderEffectType t) noexcept : type_(t), impl_(ImplFactory::CreateShaderEffectImpl()) {}
150 
GetType() const151 ShaderEffect::ShaderEffectType ShaderEffect::GetType() const
152 {
153     return type_;
154 }
155 
CreateColorShader(ColorQuad color)156 std::shared_ptr<ShaderEffect> ShaderEffect::CreateColorShader(ColorQuad color)
157 {
158     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::COLOR_SHADER, color);
159 }
160 
CreateColorSpaceShader(const Color4f & color,std::shared_ptr<ColorSpace> colorSpace)161 std::shared_ptr<ShaderEffect> ShaderEffect::CreateColorSpaceShader(const Color4f& color,
162     std::shared_ptr<ColorSpace> colorSpace)
163 {
164     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::COLOR_SHADER, color, colorSpace);
165 }
166 
CreateBlendShader(ShaderEffect & dst,ShaderEffect & src,BlendMode mode)167 std::shared_ptr<ShaderEffect> ShaderEffect::CreateBlendShader(ShaderEffect& dst, ShaderEffect& src, BlendMode mode)
168 {
169     // Check if dst shader is Lazy type, not supported for direct CreateBlendShader
170     if (dst.IsLazy()) {
171         LOGE("ShaderEffect::CreateBlendShader, dst shader is Lazy type, not supported.");
172         return nullptr;
173     }
174 
175     // Check if src shader is Lazy type, not supported for direct CreateBlendShader
176     if (src.IsLazy()) {
177         LOGE("ShaderEffect::CreateBlendShader, src shader is Lazy type, not supported.");
178         return nullptr;
179     }
180 
181     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::BLEND, dst, src, mode);
182 }
183 
CreateImageShader(const Image & image,TileMode tileX,TileMode tileY,const SamplingOptions & sampling,const Matrix & matrix)184 std::shared_ptr<ShaderEffect> ShaderEffect::CreateImageShader(
185     const Image& image, TileMode tileX, TileMode tileY, const SamplingOptions& sampling, const Matrix& matrix)
186 {
187     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::IMAGE, image, tileX, tileY, sampling, matrix);
188 }
189 
CreatePictureShader(const Picture & picture,TileMode tileX,TileMode tileY,FilterMode mode,const Matrix & matrix,const Rect & rect)190 std::shared_ptr<ShaderEffect> ShaderEffect::CreatePictureShader(
191     const Picture& picture, TileMode tileX, TileMode tileY, FilterMode mode, const Matrix& matrix, const Rect& rect)
192 {
193     return std::make_shared<ShaderEffect>(
194         ShaderEffect::ShaderEffectType::PICTURE, picture, tileX, tileY, mode, matrix, rect);
195 }
196 
CreateLinearGradient(const Point & startPt,const Point & endPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)197 std::shared_ptr<ShaderEffect> ShaderEffect::CreateLinearGradient(const Point& startPt, const Point& endPt,
198     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode, const Matrix *matrix)
199 {
200     return std::make_shared<ShaderEffect>(
201         ShaderEffect::ShaderEffectType::LINEAR_GRADIENT, startPt, endPt, colors, pos, mode, matrix);
202 }
203 
CreateLinearGradient(const Point & startPt,const Point & endPt,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)204 std::shared_ptr<ShaderEffect> ShaderEffect::CreateLinearGradient(const Point& startPt, const Point& endPt,
205     const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace, const std::vector<scalar>& pos,
206     TileMode mode, const Matrix *matrix)
207 {
208     return std::make_shared<ShaderEffect>(
209         ShaderEffect::ShaderEffectType::LINEAR_GRADIENT, startPt, endPt, colors, colorSpace, pos, mode, matrix);
210 }
211 
CreateRadialGradient(const Point & centerPt,scalar radius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)212 std::shared_ptr<ShaderEffect> ShaderEffect::CreateRadialGradient(const Point& centerPt, scalar radius,
213     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode, const Matrix *matrix)
214 {
215     return std::make_shared<ShaderEffect>(
216         ShaderEffect::ShaderEffectType::RADIAL_GRADIENT, centerPt, radius, colors, pos, mode, matrix);
217 }
218 
CreateRadialGradient(const Point & centerPt,scalar radius,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)219 std::shared_ptr<ShaderEffect> ShaderEffect::CreateRadialGradient(const Point& centerPt, scalar radius,
220     const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace, const std::vector<scalar>& pos,
221     TileMode mode, const Matrix* matrix)
222 {
223     return std::make_shared<ShaderEffect>(
224         ShaderEffect::ShaderEffectType::RADIAL_GRADIENT, centerPt, radius, colors, colorSpace, pos, mode, matrix);
225 }
226 
CreateTwoPointConical(const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)227 std::shared_ptr<ShaderEffect> ShaderEffect::CreateTwoPointConical(const Point& startPt, scalar startRadius,
228     const Point& endPt, scalar endRadius, const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos,
229     TileMode mode, const Matrix *matrix)
230 {
231     return std::make_shared<ShaderEffect>(
232         ShaderEffect::ShaderEffectType::CONICAL_GRADIENT, startPt, startRadius, endPt, endRadius, colors, pos, mode,
233         matrix);
234 }
235 
CreateTwoPointConical(const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,const Matrix * matrix)236 std::shared_ptr<ShaderEffect> ShaderEffect::CreateTwoPointConical(const Point& startPt, scalar startRadius,
237     const Point& endPt, scalar endRadius, const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace,
238     const std::vector<scalar>& pos, TileMode mode, const Matrix *matrix)
239 {
240     return std::make_shared<ShaderEffect>(
241         ShaderEffect::ShaderEffectType::CONICAL_GRADIENT, startPt, startRadius, endPt, endRadius, colors, colorSpace,
242         pos, mode, matrix);
243 }
244 
CreateSweepGradient(const Point & centerPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,scalar startAngle,scalar endAngle,const Matrix * matrix)245 std::shared_ptr<ShaderEffect> ShaderEffect::CreateSweepGradient(const Point& centerPt,
246     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode, scalar startAngle,
247     scalar endAngle, const Matrix *matrix)
248 {
249     return std::make_shared<ShaderEffect>(
250         ShaderEffect::ShaderEffectType::SWEEP_GRADIENT, centerPt, colors, pos, mode, startAngle, endAngle, matrix);
251 }
252 
CreateSweepGradient(const Point & centerPt,const std::vector<Color4f> & colors,std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar> & pos,TileMode mode,scalar startAngle,scalar endAngle,const Matrix * matrix)253 std::shared_ptr<ShaderEffect> ShaderEffect::CreateSweepGradient(const Point& centerPt,
254     const std::vector<Color4f>& colors, std::shared_ptr<ColorSpace> colorSpace,const std::vector<scalar>& pos,
255     TileMode mode, scalar startAngle, scalar endAngle, const Matrix* matrix)
256 {
257     return std::make_shared<ShaderEffect>(
258         ShaderEffect::ShaderEffectType::SWEEP_GRADIENT, centerPt, colors, colorSpace, pos, mode, startAngle,
259         endAngle, matrix);
260 }
261 
CreateExtendShader(std::shared_ptr<ExtendObject> object)262 std::shared_ptr<ShaderEffect> ShaderEffect::CreateExtendShader(std::shared_ptr<ExtendObject> object)
263 {
264     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::EXTEND_SHADER, object);
265 }
266 
CreateSdfShader(const SDFShapeBase & shape)267 std::shared_ptr<ShaderEffect> ShaderEffect::CreateSdfShader(const SDFShapeBase& shape)
268 {
269     return std::make_shared<ShaderEffect>(ShaderEffect::ShaderEffectType::SDF_SHADER, shape);
270 }
271 
272 #ifdef RS_ENABLE_GPU
SetGPUContext(std::shared_ptr<GPUContext> gpuContext) const273 void ShaderEffect::SetGPUContext(std::shared_ptr<GPUContext> gpuContext) const
274 {
275     impl_->SetGPUContext(gpuContext);
276 }
277 #endif
278 
Serialize() const279 std::shared_ptr<Data> ShaderEffect::Serialize() const
280 {
281     return impl_->Serialize();
282 }
283 
Deserialize(std::shared_ptr<Data> data)284 bool ShaderEffect::Deserialize(std::shared_ptr<Data> data)
285 {
286     return impl_->Deserialize(data);
287 }
288 
289 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)290 bool ShaderEffect::Marshalling(Parcel& parcel)
291 {
292     // Write type first
293     if (!parcel.WriteInt32(static_cast<int32_t>(type_))) {
294         LOGE("ShaderEffect::Marshalling, failed to write type");
295         return false;
296     }
297 
298     // Use Serialize to convert to Data then serialize
299     auto data = Serialize();
300 
301     // Write flag indicating whether data is valid
302     bool hasValidData = (data != nullptr && data->GetSize() > 0);
303     if (!parcel.WriteBool(hasValidData)) {
304         LOGE("ShaderEffect::Marshalling, failed to write hasData flag");
305         return false;
306     }
307 
308     // If data is null or empty (empty shader), just write the flag and return success
309     // This prevents parcel failure when underlying shader creation failed
310     if (!hasValidData) {
311         LOGD("ShaderEffect::Marshalling, Serialize returned null or empty data (empty shader), "
312              "continuing with empty marker");
313         return true;
314     }
315 
316     // Use registered callback for Data marshalling
317     auto callback = ObjectHelper::Instance().GetDataMarshallingCallback();
318     if (!callback) {
319         LOGE("ShaderEffect::Marshalling, DataMarshallingCallback is not registered");
320         return false;
321     }
322     if (!callback(parcel, data)) {
323         LOGE("ShaderEffect::Marshalling, DataMarshallingCallback failed");
324         return false;
325     }
326     return true;
327 }
328 
Unmarshalling(Parcel & parcel,bool & isValid)329 std::shared_ptr<ShaderEffect> ShaderEffect::Unmarshalling(Parcel& parcel, bool& isValid)
330 {
331     // Read type first
332     int32_t typeValue;
333     if (!parcel.ReadInt32(typeValue)) {
334         LOGE("ShaderEffect::Unmarshalling, failed to read type");
335         return nullptr;
336     }
337 
338     // Validate type range (should be valid shader types, excluding NO_TYPE and LAZY_SHADER)
339     if (typeValue < static_cast<int32_t>(ShaderEffectType::NO_TYPE) ||
340         typeValue >= static_cast<int32_t>(ShaderEffectType::LAZY_SHADER)) {
341         LOGE("ShaderEffect::Unmarshalling, invalid type value: %{public}d", typeValue);
342         return nullptr;
343     }
344 
345     // Read hasData flag
346     bool hasData;
347     if (!parcel.ReadBool(hasData)) {
348         LOGE("ShaderEffect::Unmarshalling, failed to read hasData flag");
349         return nullptr;
350     }
351 
352     // If no data (empty shader), create an empty ShaderEffect and return
353     if (!hasData) {
354         LOGD("ShaderEffect::Unmarshalling, empty shader marker detected, creating empty ShaderEffect");
355         auto shader = std::make_shared<ShaderEffect>(static_cast<ShaderEffectType>(typeValue));
356         return shader;
357     }
358 
359     // Use registered callback for Data unmarshalling
360     auto callback = ObjectHelper::Instance().GetDataUnmarshallingCallback();
361     if (!callback) {
362         LOGE("ShaderEffect::Unmarshalling, DataUnmarshallingCallback is not registered");
363         return nullptr;
364     }
365     auto data = callback(parcel);
366     if (!data) {
367         LOGE("ShaderEffect::Unmarshalling, DataUnmarshallingCallback failed");
368         return nullptr;
369     }
370 
371     // Create ShaderEffect with correct type
372     auto shader = std::make_shared<ShaderEffect>(static_cast<ShaderEffectType>(typeValue));
373     if (!shader->Deserialize(data)) {
374         LOGE("ShaderEffect::Unmarshalling, Deserialize failed");
375         // For compatibility: mark as invalid but return object instead of nullptr
376         isValid = false;
377         return shader;
378     }
379     return shader;
380 }
381 #endif
382 } // namespace Drawing
383 } // namespace Rosen
384 } // namespace OHOS
385