1 /*
2  * Copyright (c) 2024 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 <gtest/gtest.h>
17 
18 #include "ge_render.h"
19 
20 using namespace testing;
21 using namespace testing::ext;
22 
23 namespace OHOS {
24 namespace GraphicsEffectEngine {
25 
26 using namespace Rosen;
27 
28 class GERenderTest : public testing::Test {
29 public:
30     static void SetUpTestCase();
31     static void TearDownTestCase();
32     void SetUp() override;
33     void TearDown() override;
34 
35     std::shared_ptr<Drawing::Image> MakeImage(Drawing::Canvas& canvas);
36 
37     static inline Drawing::Canvas canvas_;
38 
39 private:
40     std::shared_ptr<Drawing::RuntimeEffect> MakeGreyAdjustmentEffect();
41 
42     std::shared_ptr<Drawing::RuntimeEffect> greyAdjustEffect_;
43 };
44 
SetUpTestCase(void)45 void GERenderTest::SetUpTestCase(void) {}
TearDownTestCase(void)46 void GERenderTest::TearDownTestCase(void) {}
47 
SetUp()48 void GERenderTest::SetUp()
49 {
50     canvas_.Restore();
51 }
52 
TearDown()53 void GERenderTest::TearDown() {}
54 
MakeGreyAdjustmentEffect()55 std::shared_ptr<Drawing::RuntimeEffect> GERenderTest::MakeGreyAdjustmentEffect()
56 {
57     static const std::string GreyGradationString(R"(
58         uniform shader imageShader;
59         uniform float coefficient1;
60         uniform float coefficient2;
61 
62         float poww(float x, float y) {
63             return (x < 0) ? -pow(-x, y) : pow(x, y);
64         }
65 
66         float calculateT_y(float rgb) {
67             if (rgb > 127.5) { rgb = 255 - rgb; }
68             float b = 38.0;
69             float c = 45.0;
70             float d = 127.5;
71             float A = 106.5;    // 3 * b - 3 * c + d;
72             float B = -93;      // 3 * (c - 2 * b);
73             float C = 114;      // 3 * b;
74             float p = 0.816240163988;                   // (3 * A * C - pow(B, 2)) / (3 * pow(A, 2));
75             float q = -rgb / 106.5 + 0.262253485943;    // -rgb/A - B*C/(3*pow(A,2)) + 2*pow(B,3)/(27*pow(A,3))
76             float s1 = -(q / 2.0);
77             float s2 = sqrt(pow(s1, 2) + pow(p / 3, 3));
78             return poww((s1 + s2), 1.0 / 3) + poww((s1 - s2), 1.0 / 3) - (B / (3 * A));
79         }
80 
81         float calculateGreyAdjustY(float rgb) {
82             float t_r = calculateT_y(rgb);
83             return (rgb < 127.5) ? (rgb + coefficient1 * pow((1 - t_r), 3)) : (rgb - coefficient2 * pow((1 - t_r), 3));
84         }
85 
86         vec4 main(vec2 drawing_coord) {
87             vec3 color = vec3(imageShader(drawing_coord).r, imageShader(drawing_coord).g, imageShader(drawing_coord).b);
88             float Y = (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 255;
89             float U = (-0.147 * color.r - 0.289 * color.g + 0.436 * color.b) * 255;
90             float V = (0.615 * color.r - 0.515 * color.g - 0.100 * color.b) * 255;
91             Y = calculateGreyAdjustY(Y);
92             color.r = (Y + 1.14 * V) / 255.0;
93             color.g = (Y - 0.39 * U - 0.58 * V) / 255.0;
94             color.b = (Y + 2.03 * U) / 255.0;
95 
96             return vec4(color, 1.0);
97         }
98     )");
99     if (!greyAdjustEffect_) {
100         std::shared_ptr<Drawing::RuntimeEffect> greyAdjustEffect =
101             Drawing::RuntimeEffect::CreateForShader(GreyGradationString);
102         if (!greyAdjustEffect) {
103             return nullptr;
104         }
105         greyAdjustEffect_ = std::move(greyAdjustEffect);
106     }
107 
108     return greyAdjustEffect_;
109 }
110 
MakeImage(Drawing::Canvas & canvas)111 std::shared_ptr<Drawing::Image> GERenderTest::MakeImage(Drawing::Canvas& canvas)
112 {
113     auto image = std::make_shared<Drawing::Image>();
114     if (image == nullptr) {
115         GTEST_LOG_(ERROR) << "GERenderTest::MakeImage image is null";
116         return nullptr;
117     }
118     float greyX = 0.0f;
119     float greyY = 1.0f;
120 
121     auto greyAdjustEffect = MakeGreyAdjustmentEffect();
122     if (!greyAdjustEffect) {
123         GTEST_LOG_(ERROR) << "GERenderTest::MakeImage greyAdjustEffect is null";
124         return nullptr;
125     }
126     auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(greyAdjustEffect);
127     Drawing::Matrix matrix;
128     auto imageShader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
129         Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
130     builder->SetChild("imageShader", imageShader);
131     builder->SetUniform("coefficient1", greyX);
132     builder->SetUniform("coefficient2", greyY);
133     return builder->MakeImage(canvas.GetGPUContext().get(), nullptr, image->GetImageInfo(), false);
134 }
135 
136 /**
137  * @tc.name: DrawImageEffect001
138  * @tc.desc: Verify the DrawImageEffect
139  * @tc.type: FUNC
140  */
141 HWTEST_F(GERenderTest, DrawImageEffect001, TestSize.Level1)
142 {
143     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect001 start";
144 
145     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_KAWASE_BLUR);
146     visualEffect->SetParam(Drawing::GE_FILTER_KAWASE_BLUR_RADIUS, 1);
147 
148     auto veContainer = std::make_shared<Drawing::GEVisualEffectContainer>();
149     veContainer->AddToChainedFilter(visualEffect);
150 
151     const std::shared_ptr<Drawing::Image> image = nullptr;
152     const Drawing::Rect src(1.0f, 1.0f, 1.0f, 1.0f);
153     const Drawing::Rect dst(1.0f, 1.0f, 1.0f, 1.0f);
154     const Drawing::SamplingOptions sampling;
155     auto geRender = std::make_shared<GERender>();
156     if (!geRender) {
157         GTEST_LOG_(INFO) << "GERenderTest geRender is null";
158         return;
159     }
160     geRender->DrawImageEffect(canvas_, *veContainer, image, src, dst, sampling);
161 
162     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect001 end";
163 }
164 
165 /**
166  * @tc.name: DrawImageEffect002
167  * @tc.desc: Verify the DrawImageEffect
168  * @tc.type: FUNC
169  */
170 HWTEST_F(GERenderTest, DrawImageEffect002, TestSize.Level1)
171 {
172     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect002 start";
173 
174     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_KAWASE_BLUR);
175     visualEffect->SetParam(Drawing::GE_FILTER_KAWASE_BLUR_RADIUS, 0);
176 
177     auto veContainer = std::make_shared<Drawing::GEVisualEffectContainer>();
178     veContainer->AddToChainedFilter(visualEffect);
179 
180     auto image = std::make_shared<Drawing::Image>();
181     if (!image) {
182         GTEST_LOG_(INFO) << "GERenderTest image is null";
183         return;
184     }
185     const Drawing::Rect src(1.0f, 1.0f, 1.0f, 1.0f);
186     const Drawing::Rect dst(1.0f, 1.0f, 1.0f, 1.0f);
187     const Drawing::SamplingOptions sampling;
188     auto geRender = std::make_shared<GERender>();
189     if (!geRender) {
190         GTEST_LOG_(INFO) << "GERenderTest geRender is null";
191         return;
192     }
193     geRender->DrawImageEffect(canvas_, *veContainer, image, src, dst, sampling);
194 
195     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect002 end";
196 }
197 
198 /**
199  * @tc.name: DrawImageEffect003
200  * @tc.desc: Verify the DrawImageEffect
201  * @tc.type: FUNC
202  */
203 HWTEST_F(GERenderTest, DrawImageEffect003, TestSize.Level1)
204 {
205     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect003 start";
206 
207     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_KAWASE_BLUR);
208     visualEffect->SetParam(Drawing::GE_FILTER_KAWASE_BLUR_RADIUS, 1);
209 
210     auto veContainer = std::make_shared<Drawing::GEVisualEffectContainer>();
211     veContainer->AddToChainedFilter(visualEffect);
212 
213     auto image = MakeImage(canvas_);
214     if (!image) {
215         GTEST_LOG_(INFO) << "GERenderTest image is null";
216         return;
217     }
218     const Drawing::Rect src(1.0f, 1.0f, 1.0f, 1.0f);
219     const Drawing::Rect dst(1.0f, 1.0f, 1.0f, 1.0f);
220     const Drawing::SamplingOptions sampling;
221     auto geRender = std::make_shared<GERender>();
222     if (!geRender) {
223         GTEST_LOG_(INFO) << "GERenderTest geRender is null";
224         return;
225     }
226     geRender->DrawImageEffect(canvas_, *veContainer, image, src, dst, sampling);
227 
228     GTEST_LOG_(INFO) << "GERenderTest DrawImageEffect003 end";
229 }
230 
231 /**
232  * @tc.name: ApplyImageEffect001
233  * @tc.desc: Verify the ApplyImageEffect
234  * @tc.type: FUNC
235  */
236 HWTEST_F(GERenderTest, ApplyImageEffect001, TestSize.Level1)
237 {
238     GTEST_LOG_(INFO) << "GERenderTest ApplyImageEffect001 start";
239 
240     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_KAWASE_BLUR);
241     visualEffect->SetParam(Drawing::GE_FILTER_KAWASE_BLUR_RADIUS, 1);
242 
243     auto veContainer = std::make_shared<Drawing::GEVisualEffectContainer>();
244     veContainer->AddToChainedFilter(visualEffect);
245 
246     const std::shared_ptr<Drawing::Image> image = nullptr;
247     const Drawing::Rect src(1.0f, 1.0f, 1.0f, 1.0f);
248     const Drawing::Rect dst(1.0f, 1.0f, 1.0f, 1.0f);
249     const Drawing::SamplingOptions sampling;
250     auto geRender = std::make_shared<GERender>();
251     if (!geRender) {
252         GTEST_LOG_(INFO) << "GERenderTest geRender is null";
253         return;
254     }
255     auto outImage = geRender->ApplyImageEffect(canvas_, *veContainer, image, src, dst, sampling);
256     EXPECT_TRUE(outImage == image);
257 
258     GTEST_LOG_(INFO) << "GERenderTest ApplyImageEffect001 end";
259 }
260 
261 /**
262  * @tc.name: GenerateShaderFilter001
263  * @tc.desc: Verify the GenerateShaderFilter
264  * @tc.type: FUNC
265  */
266 HWTEST_F(GERenderTest, GenerateShaderFilter001, TestSize.Level1)
267 {
268     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter001 start";
269 
270     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_AI_BAR);
271     visualEffect->SetParam(Drawing::GE_FILTER_AI_BAR_LOW, 1.0f); // 1.0 AI bar blur low
272     visualEffect->SetParam(Drawing::GE_FILTER_AI_BAR_HIGH, 1.0f); // 1.0 AI bar blur high
273     visualEffect->SetParam(Drawing::GE_FILTER_AI_BAR_THRESHOLD, 1.0f); // 1.0 AI bar blur threshold
274     visualEffect->SetParam(Drawing::GE_FILTER_AI_BAR_OPACITY, 1.0f); // 1.0 AI bar blur opacity
275     visualEffect->SetParam(Drawing::GE_FILTER_AI_BAR_SATURATION, 1.0f); // 1.0 AI bar blur saturation
276     Drawing::GEVisualEffectContainer veContainer;
277     veContainer.AddToChainedFilter(visualEffect);
278     auto geRender = std::make_shared<GERender>();
279     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
280     EXPECT_NE(shaderFilters[0], nullptr);
281 
282     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter001 end";
283 }
284 
285 /**
286  * @tc.name: GenerateShaderFilter002
287  * @tc.desc: Verify the GenerateShaderFilter
288  * @tc.type: FUNC
289  */
290 HWTEST_F(GERenderTest, GenerateShaderFilter002, TestSize.Level1)
291 {
292     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter002 start";
293 
294     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_GREY);
295     visualEffect->SetParam(Drawing::GE_FILTER_GREY_COEF_1, 1.0f); // 1.0 grey blur coff
296     visualEffect->SetParam(Drawing::GE_FILTER_GREY_COEF_2, 1.0f); // 1.0 grey blur coff
297     Drawing::GEVisualEffectContainer veContainer;
298     veContainer.AddToChainedFilter(visualEffect);
299     auto geRender = std::make_shared<GERender>();
300     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
301     EXPECT_NE(shaderFilters[0], nullptr);
302 
303     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter002 end";
304 }
305 
306 /**
307  * @tc.name: GenerateShaderFilter003
308  * @tc.desc: Verify the GenerateShaderFilter
309  * @tc.type: FUNC
310  */
311 HWTEST_F(GERenderTest, GenerateShaderFilter003, TestSize.Level1)
312 {
313     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter003 start";
314 
315     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_LINEAR_GRADIENT_BLUR);
316     visualEffect->SetParam(Drawing::GE_FILTER_LINEAR_GRADIENT_BLUR_DIRECTION, 1); // 1 blur directon
317     Drawing::GEVisualEffectContainer veContainer;
318     veContainer.AddToChainedFilter(visualEffect);
319     auto geRender = std::make_shared<GERender>();
320     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
321     EXPECT_NE(shaderFilters[0], nullptr);
322 
323     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter003 end";
324 }
325 
326 /**
327  * @tc.name: GenerateShaderFilter004
328  * @tc.desc: Verify the GenerateShaderFilter
329  * @tc.type: FUNC
330  */
331 HWTEST_F(GERenderTest, GenerateShaderFilter004, TestSize.Level1)
332 {
333     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter004 start";
334 
335     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>("");
336     visualEffect->SetParam(Drawing::GE_FILTER_LINEAR_GRADIENT_BLUR_DIRECTION, 1); // 1 blur directon
337     Drawing::GEVisualEffectContainer veContainer;
338     veContainer.AddToChainedFilter(visualEffect);
339     auto geRender = std::make_shared<GERender>();
340     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
341     EXPECT_EQ(shaderFilters[0], nullptr);
342 
343     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter003 end";
344 }
345 
346 /**
347  * @tc.name: GenerateShaderFilterMESA
348  * @tc.desc: Verify the GenerateShaderFilter
349  * @tc.type: FUNC
350  */
351 HWTEST_F(GERenderTest, GenerateShaderFilterMESA, TestSize.Level1)
352 {
353     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilterMESA start";
354 
355     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_MESA_BLUR);
356     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_RADIUS, 1); // 1 blur directon
357     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_GREY_COEF_1, 1.0f); // 1.0 grey blur coff
358     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_GREY_COEF_2, 1.0f); // 1.0 grey blur coff
359     // 0, 0.0: tileMode and stretch params
360     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_OFFSET_X, 0.0f);
361     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_OFFSET_Y, 0.0f);
362     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_OFFSET_Z, 0.0f);
363     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_OFFSET_W, 0.0f);
364     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_TILE_MODE, 0);
365     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_WIDTH, 0.0f);
366     visualEffect->SetParam(Drawing::GE_FILTER_MESA_BLUR_STRETCH_HEIGHT, 0.0f);
367     Drawing::GEVisualEffectContainer veContainer;
368     veContainer.AddToChainedFilter(visualEffect);
369     auto geRender = std::make_shared<GERender>();
370     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
371     EXPECT_NE(shaderFilters[0], nullptr);
372 
373     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilterMESA end";
374 }
375 
376 /**
377  * @tc.name: GenerateShaderFilter005
378  * @tc.desc: Verify the GenerateShaderFilter
379  * @tc.type: FUNC
380  */
381 HWTEST_F(GERenderTest, GenerateShaderFilter005, TestSize.Level1)
382 {
383     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter005 start";
384 
385     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_WATER_RIPPLE);
386     visualEffect->SetParam("PROGRESS", 0.5f);
387     visualEffect->SetParam("WAVE_NUM", 1.0f);
388     visualEffect->SetParam("RIPPLE_CENTER_X", 0.5f);
389     visualEffect->SetParam("RIPPLE_CENTER_Y", 0.5f);
390     Drawing::GEVisualEffectContainer veContainer;
391     veContainer.AddToChainedFilter(visualEffect);
392     auto geRender = std::make_shared<GERender>();
393     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
394     EXPECT_NE(shaderFilters[0], nullptr);
395 
396     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter005 end";
397 }
398 
399 /**
400  * @tc.name: GenerateShaderFilter006
401  * @tc.desc: Verify the GenerateShaderFilter
402  * @tc.type: FUNC
403  */
404 HWTEST_F(GERenderTest, GenerateShaderFilter006, TestSize.Level1)
405 {
406     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter006 start";
407 
408     auto visualEffect = std::make_shared<Drawing::GEVisualEffect>(Drawing::GE_FILTER_MAGNIFIER);
409     Drawing::GEVisualEffectContainer veContainer;
410     veContainer.AddToChainedFilter(visualEffect);
411     auto geRender = std::make_shared<GERender>();
412     auto shaderFilters = geRender->GenerateShaderFilter(veContainer);
413     EXPECT_NE(shaderFilters[0], nullptr);
414 
415     GTEST_LOG_(INFO) << "GERenderTest GenerateShaderFilter006 end";
416 }
417 
418 } // namespace GraphicsEffectEngine
419 } // namespace OHOS
420