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