1 /*
2 * Copyright (c) 2024-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 <cstddef>
17 #include "gtest/gtest.h"
18 #include "skia_adapter/skia_canvas_autocache.h"
19 #include "draw/core_canvas.h"
20 #include "draw/paint.h"
21 #include "skia_adapter/skia_convert_utils.h"
22 #include "skia_adapter/skia_data.h"
23 #include "skia_adapter/skia_image.h"
24 #include "skia_adapter/skia_image_info.h"
25 #include "skia_adapter/skia_matrix.h"
26 #include "skia_adapter/skia_paint.h"
27 #include "skia_adapter/skia_path.h"
28 #include "skia_adapter/skia_region.h"
29 #include "skia_adapter/skia_text_blob.h"
30 #include "skia_adapter/skia_vertices.h"
31 #include "text/rs_xform.h"
32 #include "utils/rect.h"
33
34 using namespace testing;
35 using namespace testing::ext;
36
37 namespace OHOS {
38 namespace Rosen {
39 namespace Drawing {
40 class SkiaCanvasAutoCacheTest : public testing::Test {
41 public:
42 static void SetUpTestCase();
43 static void TearDownTestCase();
44 void SetUp() override;
45 void TearDown() override;
46 };
47
SetUpTestCase()48 void SkiaCanvasAutoCacheTest::SetUpTestCase() {}
TearDownTestCase()49 void SkiaCanvasAutoCacheTest::TearDownTestCase() {}
SetUp()50 void SkiaCanvasAutoCacheTest::SetUp() {}
TearDown()51 void SkiaCanvasAutoCacheTest::TearDown() {}
52
53 /**
54 * @tc.name: SkiaCanvasAutoCache001
55 * @tc.desc: Test SkiaCanvasAutoCache
56 * @tc.type: FUNC
57 * @tc.require: I8VQSW
58 */
59 HWTEST_F(SkiaCanvasAutoCacheTest, SkiaCanvasAutoCache001, TestSize.Level1)
60 {
61 SkCanvas canvas;
62 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
63 ASSERT_TRUE(skiaCanvasAutoCache != nullptr);
64 }
65
66 /**
67 * @tc.name: Init001
68 * @tc.desc: Test SkiaCanvasAutoCache
69 * @tc.type: FUNC
70 * @tc.require: I8VQSW
71 */
72 HWTEST_F(SkiaCanvasAutoCacheTest, Init001, TestSize.Level1)
73 {
74 SkCanvas canvas;
75 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
76 auto originMatrix = skiaCanvasAutoCache->nodeMatrix_;
77 SkMatrix m;
78 skiaCanvasAutoCache->Init(m);
79 ASSERT_TRUE(skiaCanvasAutoCache->nodeMatrix_ == originMatrix);
80 }
81
82 /**
83 * @tc.name: OpCanCache001
84 * @tc.desc: Test SkiaCanvasAutoCache
85 * @tc.type: FUNC
86 * @tc.require: I8VQSW
87 */
88 HWTEST_F(SkiaCanvasAutoCacheTest, OpCanCache001, TestSize.Level1)
89 {
90 SkCanvas canvas;
91 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
92 auto v = skiaCanvasAutoCache->GetOpListDrawArea();
93 ASSERT_TRUE(v.size() == 0);
94 }
95
96 /**
97 * @tc.name: GetOpUnionRect001
98 * @tc.desc: Test SkiaCanvasAutoCache
99 * @tc.type: FUNC
100 * @tc.require: I8VQSW
101 */
102 HWTEST_F(SkiaCanvasAutoCacheTest, GetOpUnionRect001, TestSize.Level1)
103 {
104 SkCanvas canvas;
105 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
106 ASSERT_TRUE(skiaCanvasAutoCache->GetOpUnionRect().isEmpty());
107 }
108
109 /**
110 * @tc.name: GetOpsNum001
111 * @tc.desc: Test SkiaCanvasAutoCache
112 * @tc.type: FUNC
113 * @tc.require: I8VQSW
114 */
115 HWTEST_F(SkiaCanvasAutoCacheTest, GetOpsNum001, TestSize.Level1)
116 {
117 SkCanvas canvas;
118 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
119 ASSERT_TRUE(skiaCanvasAutoCache->GetOpsNum() == 0);
120 }
121
122 /**
123 * @tc.name: GetOpsPercent001
124 * @tc.desc: Test SkiaCanvasAutoCache
125 * @tc.type: FUNC
126 * @tc.require: I8VQSW
127 */
128 HWTEST_F(SkiaCanvasAutoCacheTest, GetOpsPercent001, TestSize.Level1)
129 {
130 SkCanvas canvas;
131 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
132 ASSERT_TRUE(skiaCanvasAutoCache->GetOpsPercent() == 0);
133 }
134
135 /**
136 * @tc.name: ShowDrawResult001
137 * @tc.desc: Test SkiaCanvasAutoCache
138 * @tc.type: FUNC
139 * @tc.require: I8VQSW
140 */
141 HWTEST_F(SkiaCanvasAutoCacheTest, ShowDrawResult001, TestSize.Level1)
142 {
143 SkCanvas canvas;
144 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
145 ASSERT_TRUE(skiaCanvasAutoCache->GetOpsPercent() == 0);
146 SkRect bound;
147 skiaCanvasAutoCache->ShowDrawResult(bound);
148 }
149
150 /**
151 * @tc.name: getBaseLayerSize001
152 * @tc.desc: Test SkiaCanvasAutoCache
153 * @tc.type: FUNC
154 * @tc.require: I8VQSW
155 */
156 HWTEST_F(SkiaCanvasAutoCacheTest, getBaseLayerSize001, TestSize.Level1)
157 {
158 SkCanvas canvas;
159 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
160 SkISize size = skiaCanvasAutoCache->getBaseLayerSize();
161 ASSERT_TRUE(size.area() == 0);
162 }
163
164 /**
165 * @tc.name: recordingContext001
166 * @tc.desc: Test SkiaCanvasAutoCache
167 * @tc.type: FUNC
168 * @tc.require: I8VQSW
169 */
170 HWTEST_F(SkiaCanvasAutoCacheTest, recordingContext001, TestSize.Level1)
171 {
172 SkCanvas canvas;
173 std::shared_ptr<SkiaCanvasAutoCache> skiaCanvasAutoCache = std::make_shared<SkiaCanvasAutoCache>(&canvas);
174 ASSERT_TRUE(skiaCanvasAutoCache->recordingContext() == nullptr);
175 }
176
177 /**
178 * @tc.name: RecordDrawArea001
179 * @tc.desc: Test SkiaCanvasAutoCache
180 * @tc.type: FUNC
181 * @tc.require: IAKGJ7
182 */
183 HWTEST_F(SkiaCanvasAutoCacheTest, RecordDrawArea001, TestSize.Level1)
184 {
185 SkCanvas canvas;
186 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
187 const SkRect bounds = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
188 Paint paint;
189 paint.SetAntiAlias(true);
190 SkPaint skPaint;
191 SkiaPaint::PaintToSkPaint(paint, skPaint);
192 SkiaMatrix skiaMatrix;
193 skiaMatrix.Scale(2, 2, 2, 2); // 2: sx, sy, px, py
194 SkMatrix skMatrix = skiaMatrix.ExportSkiaMatrix();
195 bool isRecordDrawArea = false;
196 isRecordDrawArea = skiaCanvasAutoCache.RecordDrawArea(bounds, skPaint, &skMatrix);
197 ASSERT_TRUE(isRecordDrawArea);
198
199 SkiaImage skiaImage;
200 const SamplingOptions sampling;
201 const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
202 SkRect dstBounds = SkRect::MakeEmpty();
203 skiaCanvasAutoCache.onDrawImageRect2(skiaImage.GetImage().get(), bounds, dstBounds, *samplingOptions, &skPaint,
204 static_cast<SkCanvas::SrcRectConstraint>(SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT));
205 }
206
207 /**
208 * @tc.name: OpCanCache002
209 * @tc.desc: Test SkiaCanvasAutoCache
210 * @tc.type: FUNC
211 * @tc.require: IAKGJ7
212 */
213 HWTEST_F(SkiaCanvasAutoCacheTest, OpCanCache002, TestSize.Level1)
214 {
215 SkCanvas canvas;
216 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
217 skiaCanvasAutoCache.opCanCache_ = true;
218 skiaCanvasAutoCache.totalOpNums_ = 2;
219 const SkRect boundsFirst = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
220 skiaCanvasAutoCache.drawAreaRects_.emplace_back(boundsFirst);
221 const SkRect boundsSecond = SkRect::MakeLTRB(150, 150, 450, 350); // rect.Left, rect.Top, rect.Right, rect.Bottom
222 skiaCanvasAutoCache.drawAreaRects_.emplace_back(boundsSecond);
223 ASSERT_TRUE(skiaCanvasAutoCache.drawAreaRects_.size() != 0);
224
225 skiaCanvasAutoCache.MergeDrawAreaRects();
226 bool isOpCanCache = false;
227 isOpCanCache = skiaCanvasAutoCache.OpCanCache(boundsFirst);
228 ASSERT_TRUE(!isOpCanCache);
229 }
230
231 /**
232 * @tc.name: onDrawVerticesObject001
233 * @tc.desc: Test SkiaCanvasAutoCache
234 * @tc.type: FUNC
235 * @tc.require: IAKGJ7
236 */
237 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawVerticesObject001, TestSize.Level1)
238 {
239 SkCanvas canvas;
240 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
241 SkiaVertices vertices;
242 Paint paint;
243 paint.SetAntiAlias(true);
244 SkPaint skPaint;
245 SkiaPaint::PaintToSkPaint(paint, skPaint);
246 skiaCanvasAutoCache.onDrawVerticesObject(vertices.GetVertices().get(),
247 static_cast<SkBlendMode>(BlendMode::CLEAR), skPaint);
248
249 const SkRect skBounds = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
250 SkCanvas::SaveLayerRec slr(&skBounds, &skPaint);
251 SkCanvas::SaveLayerStrategy saveLayerStrategy = SkCanvas::SaveLayerStrategy::kFullLayer_SaveLayerStrategy;
252 saveLayerStrategy = skiaCanvasAutoCache.getSaveLayerStrategy(slr);
253 ASSERT_TRUE(saveLayerStrategy == SkCanvas::SaveLayerStrategy::kNoLayer_SaveLayerStrategy);
254 bool isOnDoSaveBehind = true;
255 isOnDoSaveBehind = skiaCanvasAutoCache.onDoSaveBehind(&skBounds);
256 ASSERT_TRUE(!isOnDoSaveBehind);
257 }
258
259 /**
260 * @tc.name: onDrawPaint001
261 * @tc.desc: Test SkiaCanvasAutoCache
262 * @tc.type: FUNC
263 * @tc.require: IAKGJ7
264 */
265 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawPaint001, TestSize.Level1)
266 {
267 SkCanvas canvas;
268 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
269 Paint paint;
270 paint.SetAntiAlias(true);
271 SkPaint skPaint;
272 SkiaPaint::PaintToSkPaint(paint, skPaint);
273 skiaCanvasAutoCache.onDrawPaint(skPaint);
274 skiaCanvasAutoCache.onDrawBehind(skPaint);
275
276 SkPoint point1;
277 point1.Make(100.f, 100.f); // 100.f, 100.f means coordinates of points
278 SkPoint point2;
279 point2.Make(200.f, 200.f); // 200.f, 200.f means coordinates of points
280 SkPoint pts[] = {point1, point2};
281 skiaCanvasAutoCache.onDrawPoints(static_cast<SkCanvas::PointMode>(PointMode::POINTS_POINTMODE),
282 2, pts, skPaint); //2 is pts count
283
284 const SkRect skBounds = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
285 skiaCanvasAutoCache.onDrawRect(skBounds, skPaint);
286
287 SkRRect skRRect;
288 skRRect = SkRRect::MakeRect(skBounds);
289 skiaCanvasAutoCache.onDrawRRect(skRRect, skPaint);
290
291 SkRRect skRRectOuter;
292 skiaCanvasAutoCache.onDrawDRRect(skRRectOuter, skRRect, skPaint);
293
294 SkIRect skIRect;
295 skIRect = SkIRect::MakeWH(200, 300); // 200, 300 means width and height of constructed SkIRect
296 SkRegion skRegion;
297 bool isRegionSetRect = false;
298 isRegionSetRect = skRegion.setRect(skIRect);
299 ASSERT_TRUE(isRegionSetRect);
300 skiaCanvasAutoCache.onDrawRegion(skRegion, skPaint);
301 }
302
303 /**
304 * @tc.name: onDrawOval001
305 * @tc.desc: Test SkiaCanvasAutoCache
306 * @tc.type: FUNC
307 * @tc.require: IAKGJ7
308 */
309 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawOval001, TestSize.Level1)
310 {
311 SkCanvas canvas;
312 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
313 Paint paint;
314 paint.SetAntiAlias(true);
315 SkPaint skPaint;
316 SkiaPaint::PaintToSkPaint(paint, skPaint);
317
318 const SkRect skRect = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
319 skiaCanvasAutoCache.onDrawOval(skRect, skPaint);
320 ASSERT_TRUE(skiaCanvasAutoCache.OpShouldRecord());
321 skiaCanvasAutoCache.onDrawArc(skRect, 90.f, 360.f, false, skPaint); // 90.f 360.f means startAngle and sweepAngle
322 ASSERT_TRUE(skiaCanvasAutoCache.OpShouldRecord());
323 SkiaPath skiaPath;
324 skiaPath.AddRoundRect(0, 0,
325 100, 100, 100, 100, PathDirection::CW_DIRECTION); // 100: right, bottom, xRadius, yRadius
326 skiaCanvasAutoCache.onDrawPath(skiaPath.GetPath(), skPaint);
327 }
328
329 /**
330 * @tc.name: onDrawImage2001
331 * @tc.desc: Test SkiaCanvasAutoCache
332 * @tc.type: FUNC
333 * @tc.require: IAKGJ7
334 */
335 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawImage2001, TestSize.Level1)
336 {
337 SkCanvas canvas;
338 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
339 Paint paint;
340 paint.SetAntiAlias(true);
341 SkPaint skPaint;
342 SkiaPaint::PaintToSkPaint(paint, skPaint);
343 SkImageInfo info;
344 info.makeWH(300, 500); // 300, 500 means newWidth and newHeight
345 SkImage image(info, 1); // 1 means uniqueID
346 const SamplingOptions sampling;
347 const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
348 ASSERT_TRUE(samplingOptions != nullptr);
349 skiaCanvasAutoCache.onDrawImage2(&image, 100.f, 200.f, *samplingOptions,
350 &skPaint); // 100.f, 200.f means left and top
351
352 const SkRect skRect = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
353 SkCanvas::Lattice lattice;
354 skiaCanvasAutoCache.onDrawImageLattice2(&image, lattice, skRect,
355 static_cast<SkFilterMode>(FilterMode::LINEAR), &skPaint);
356 }
357
358 /**
359 * @tc.name: onDrawTextBlob001
360 * @tc.desc: Test SkiaCanvasAutoCache
361 * @tc.type: FUNC
362 * @tc.require: IAKGJ7
363 */
364 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawTextBlob001, TestSize.Level1)
365 {
366 SkCanvas canvas;
367 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
368 Paint paint;
369 paint.SetAntiAlias(true);
370 SkPaint skPaint;
371 SkiaPaint::PaintToSkPaint(paint, skPaint);
372 const char* str = "asdf";
373 Font font;
374 font.SetSize(100);
375 auto textBlob = SkiaTextBlob::MakeFromText(str, strlen(str), font, TextEncoding::UTF8);
376 ASSERT_TRUE(textBlob != nullptr);
377 auto skiaBlobImpl = textBlob->GetImpl<SkiaTextBlob>();
378 ASSERT_TRUE(skiaBlobImpl != nullptr);
379
380 skiaCanvasAutoCache.onDrawTextBlob(skiaBlobImpl->GetTextBlob().get(), 100.f, 100.f, skPaint); // 100 means location
381 }
382
383 /**
384 * @tc.name: onDrawAtlas2001
385 * @tc.desc: Test SkiaCanvasAutoCache
386 * @tc.type: FUNC
387 * @tc.require: IAKGJ7
388 */
389 HWTEST_F(SkiaCanvasAutoCacheTest, onDrawAtlas2001, TestSize.Level1)
390 {
391 SkCanvas canvas;
392 SkiaCanvasAutoCache skiaCanvasAutoCache(&canvas);
393 Paint paint;
394 paint.SetAntiAlias(true);
395 SkPaint skPaint;
396 SkiaPaint::PaintToSkPaint(paint, skPaint);
397 std::shared_ptr<SkiaImage> skiaImage = std::make_shared<SkiaImage>();
398 RSXform xform = RSXform::Make(10, 10, 10, 10);
399 SkRSXform& rSXform = reinterpret_cast<SkRSXform&>(xform);
400 SkRSXform rSXformArray[2] = {rSXform, rSXform}; // 2 means array size
401 Rect rect(100, 100, 400, 300); // 100, 100, 400, 300 means rect.Left, rect.Top, rect.Right, rect.Bottom
402 SkRect* skBounds = reinterpret_cast<SkRect*>(&rect);
403 ASSERT_TRUE(skBounds != nullptr);
404 SkRect skBoundsArray[2] = {*skBounds, *skBounds}; // 2 means array size
405 Color color(123, 33, 50, 1);
406 SkColor* skColor = reinterpret_cast<SkColor*>(&color);
407 SkColor skColorArray[2] = {*skColor, *skColor}; // 2 means array size
408 const SamplingOptions sampling;
409 const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
410 ASSERT_TRUE(samplingOptions != nullptr);
411 const SkRect cull = SkRect::MakeLTRB(100, 100, 400, 300); // rect.Left, rect.Top, rect.Right, rect.Bottom
412
413 skiaCanvasAutoCache.onDrawAtlas2(skiaImage->GetImage().get(), rSXformArray, skBoundsArray, skColorArray,
414 2, static_cast<SkBlendMode>(BlendMode::CLEAR), *samplingOptions, &cull, &skPaint);
415 }
416 } // namespace Drawing
417 } // namespace Rosen
418 } // namespace OHOS