blob: c9e8d808f9955d483aa01b97182cd0ab47198719 [file] [log] [blame]
John Reck013127b2020-10-29 20:53:51 -04001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
John Reckdc95f102020-11-16 12:35:02 -050019#include <canvas/CanvasFrontend.h>
John Reck013127b2020-10-29 20:53:51 -040020#include <canvas/CanvasOpBuffer.h>
21#include <canvas/CanvasOps.h>
22#include <canvas/CanvasOpRasterizer.h>
23
24#include <tests/common/CallCountingCanvas.h>
25
Nader Jawadda9248c2020-11-09 17:27:36 -080026#include "SkPictureRecorder.h"
Nader Jawadde3ce842020-11-06 16:54:48 -080027#include "SkColor.h"
Nader Jawadda9248c2020-11-09 17:27:36 -080028#include "SkLatticeIter.h"
Nader Jawadde3ce842020-11-06 16:54:48 -080029#include "pipeline/skia/AnimatedDrawables.h"
John Reckdc95f102020-11-16 12:35:02 -050030#include <SkNoDrawCanvas.h>
Nader Jawadde3ce842020-11-06 16:54:48 -080031
John Reck013127b2020-10-29 20:53:51 -040032using namespace android;
33using namespace android::uirenderer;
34using namespace android::uirenderer::test;
35
36// We lazy
37using Op = CanvasOpType;
38
John Reckdc95f102020-11-16 12:35:02 -050039class CanvasOpCountingReceiver {
40public:
41 template <CanvasOpType T>
42 void push_container(CanvasOpContainer<T>&& op) {
43 mOpCounts[static_cast<size_t>(T)] += 1;
44 }
45
46 int operator[](CanvasOpType op) const {
47 return mOpCounts[static_cast<size_t>(op)];
48 }
49
50private:
51 std::array<int, static_cast<size_t>(CanvasOpType::COUNT)> mOpCounts;
52};
53
John Reck013127b2020-10-29 20:53:51 -040054template<typename T>
55static int countItems(const T& t) {
56 int count = 0;
57 t.for_each([&](auto i) {
58 count++;
59 });
60 return count;
61}
62
John Reck90b0a1c2020-11-12 12:37:30 -050063TEST(CanvasOp, verifyConst) {
64 CanvasOpBuffer buffer;
65 buffer.push<Op::DrawColor>({
66 .color = SkColors::kBlack,
67 .mode = SkBlendMode::kSrcOver,
68 });
69 buffer.for_each([](auto op) {
70 static_assert(std::is_const_v<std::remove_reference_t<decltype(*op)>>,
71 "Expected container to be const");
72 static_assert(std::is_const_v<std::remove_reference_t<decltype(op->op())>>,
73 "Expected op to be const");
74 });
75}
76
John Reck013127b2020-10-29 20:53:51 -040077TEST(CanvasOp, simplePush) {
78 CanvasOpBuffer buffer;
79 EXPECT_EQ(buffer.size(), 0);
80 buffer.push<Op::Save>({});
81 buffer.push<Op::Save>({});
82 buffer.push<Op::Restore>({});
83 EXPECT_GT(buffer.size(), 0);
84
85 int saveCount = 0;
86 int restoreCount = 0;
87 int otherCount = 0;
88
89 buffer.for_each([&](auto op) {
90 switch (op->type()) {
91 case Op::Save:
92 saveCount++;
93 break;
94 case Op::Restore:
95 restoreCount++;
96 break;
97 default:
98 otherCount++;
99 break;
100 }
101 });
102
103 EXPECT_EQ(saveCount, 2);
104 EXPECT_EQ(restoreCount, 1);
105 EXPECT_EQ(otherCount, 0);
106
107 buffer.clear();
108 int itemCount = 0;
109 buffer.for_each([&](auto op) {
110 itemCount++;
111 });
112 EXPECT_EQ(itemCount, 0);
113 buffer.resize(0);
114 EXPECT_EQ(buffer.size(), 0);
115}
116
Nader Jawadde3ce842020-11-06 16:54:48 -0800117TEST(CanvasOp, simpleDrawPaint) {
118 CanvasOpBuffer buffer;
119 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800120 buffer.push<Op::DrawColor> ({
Nader Jawadde3ce842020-11-06 16:54:48 -0800121 .color = SkColor4f{1, 1, 1, 1},
122 .mode = SkBlendMode::kSrcIn
123 });
124
125 CallCountingCanvas canvas;
126 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
127 rasterizeCanvasBuffer(buffer, &canvas);
128 EXPECT_EQ(1, canvas.drawPaintCount);
129 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
130}
131
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800132TEST(CanvasOp, simpleDrawPoint) {
133 CanvasOpBuffer buffer;
134 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800135 buffer.push<Op::DrawPoint> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800136 .x = 12,
137 .y = 42,
138 .paint = SkPaint{}
139 });
140
141 CallCountingCanvas canvas;
142 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
143 rasterizeCanvasBuffer(buffer, &canvas);
144 EXPECT_EQ(1, canvas.drawPoints);
145 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
146}
147
Nader Jawad4285c8a2020-11-06 22:49:42 -0800148TEST(CanvasOp, simpleDrawPoints) {
149 CanvasOpBuffer buffer;
150 EXPECT_EQ(buffer.size(), 0);
151 size_t numPts = 3;
152 auto pts = sk_ref_sp(
153 new Points({
154 {32, 16},
155 {48, 48},
156 {16, 32}
157 })
158 );
159
160 buffer.push(CanvasOp<Op::DrawPoints> {
161 .count = numPts,
162 .paint = SkPaint{},
163 .points = pts
164 });
165
166 CallCountingCanvas canvas;
167 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
168 rasterizeCanvasBuffer(buffer, &canvas);
169 EXPECT_EQ(1, canvas.drawPoints);
170 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
171}
172
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800173TEST(CanvasOp, simpleDrawLine) {
174 CanvasOpBuffer buffer;
175 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800176 buffer.push<Op::DrawLine> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800177 .startX = 16,
178 .startY = 28,
179 .endX = 12,
180 .endY = 30,
181 .paint = SkPaint{}
182 });
183
184 CallCountingCanvas canvas;
185 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
186 rasterizeCanvasBuffer(buffer, &canvas);
187 EXPECT_EQ(1, canvas.drawPoints);
188 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
189}
190
Nader Jawad4285c8a2020-11-06 22:49:42 -0800191TEST(CanvasOp, simpleDrawLines) {
192 CanvasOpBuffer buffer;
193 EXPECT_EQ(buffer.size(), 0);
194 size_t numPts = 3;
195 auto pts = sk_ref_sp(
196 new Points({
197 {32, 16},
198 {48, 48},
199 {16, 32}
200 })
201 );
202 buffer.push(CanvasOp<Op::DrawLines> {
203 .count = numPts,
204 .paint = SkPaint{},
205 .points = pts
206 });
207
208 CallCountingCanvas canvas;
209 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
210 rasterizeCanvasBuffer(buffer, &canvas);
211 EXPECT_EQ(1, canvas.drawPoints);
212 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
213}
214
John Reck013127b2020-10-29 20:53:51 -0400215TEST(CanvasOp, simpleDrawRect) {
216 CanvasOpBuffer buffer;
217 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800218 buffer.push<Op::DrawRect> ({
John Reck013127b2020-10-29 20:53:51 -0400219 .paint = SkPaint{},
220 .rect = SkRect::MakeEmpty()
221 });
222
223 CallCountingCanvas canvas;
224 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
225 rasterizeCanvasBuffer(buffer, &canvas);
226 EXPECT_EQ(1, canvas.drawRectCount);
227 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
228}
229
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800230TEST(CanvasOp, simpleDrawRegionRect) {
231 CanvasOpBuffer buffer;
232 EXPECT_EQ(buffer.size(), 0);
233 SkRegion region;
234 region.setRect(SkIRect::MakeWH(12, 50));
Nader Jawadda9248c2020-11-09 17:27:36 -0800235 buffer.push<Op::DrawRegion> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800236 .paint = SkPaint{},
237 .region = region
238 });
239
240 CallCountingCanvas canvas;
241 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
242 rasterizeCanvasBuffer(buffer, &canvas);
243 // If the region is a rectangle, drawRegion calls into drawRect as a fast path
244 EXPECT_EQ(1, canvas.drawRectCount);
245 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
246}
247
248TEST(CanvasOp, simpleDrawRegionPath) {
249 CanvasOpBuffer buffer;
250 EXPECT_EQ(buffer.size(), 0);
251 SkPath path;
252 path.addCircle(50, 50, 50);
253 SkRegion clip;
254 clip.setRect(SkIRect::MakeWH(100, 100));
255 SkRegion region;
256 region.setPath(path, clip);
Nader Jawadda9248c2020-11-09 17:27:36 -0800257 buffer.push<Op::DrawRegion> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800258 .paint = SkPaint{},
259 .region = region
260 });
261
262 CallCountingCanvas canvas;
263 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
264 rasterizeCanvasBuffer(buffer, &canvas);
265 EXPECT_EQ(1, canvas.drawRegionCount);
266 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
267}
268
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800269TEST(CanvasOp, simpleDrawRoundRect) {
270 CanvasOpBuffer buffer;
271 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800272 buffer.push<Op::DrawRoundRect> ({
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800273 .paint = SkPaint{},
274 .rect = SkRect::MakeEmpty(),
275 .rx = 10,
276 .ry = 10
277 });
278
279 CallCountingCanvas canvas;
280 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
281 rasterizeCanvasBuffer(buffer, &canvas);
282 EXPECT_EQ(1, canvas.drawRRectCount);
283 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
284}
285
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800286TEST(CanvasOp, simpleDrawDoubleRoundRect) {
287 CanvasOpBuffer buffer;
288 EXPECT_EQ(buffer.size(), 0);
289 SkRect outer = SkRect::MakeLTRB(0, 0, 100, 100);
290 SkRect inner = SkRect::MakeLTRB(20, 20, 80, 80);
291
292 const int numPts = 4;
293 SkRRect outerRRect;
294
295 auto outerPts = std::make_unique<SkVector[]>(numPts);
296 outerPts[0].set(32, 16);
297 outerPts[1].set(48, 48);
298 outerPts[2].set(16, 32);
299 outerPts[3].set(20, 20);
300 outerRRect.setRectRadii(outer, outerPts.get());
301 outerRRect.setRect(outer);
302
303 SkRRect innerRRect;
304 auto innerPts = std::make_unique<SkVector[]>(numPts);
305 innerPts[0].set(16, 8);
306 innerPts[1].set(24, 24);
307 innerPts[2].set(8, 16);
308 innerPts[3].set(10, 10);
309 innerRRect.setRectRadii(inner, innerPts.get());
310
Nader Jawadda9248c2020-11-09 17:27:36 -0800311 buffer.push<Op::DrawDoubleRoundRect> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800312 .outer = outerRRect,
313 .inner = innerRRect,
314 .paint = SkPaint{}
315 });
316
317 CallCountingCanvas canvas;
318 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
319 rasterizeCanvasBuffer(buffer, &canvas);
320 EXPECT_EQ(1, canvas.drawDRRectCount);
321 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
322}
323
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800324TEST(CanvasOp, simpleDrawCircle) {
325 CanvasOpBuffer buffer;
326 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800327 buffer.push<Op::DrawCircle>({
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800328 .cx = 5,
329 .cy = 7,
330 .radius = 10,
331 .paint = SkPaint{}
332 });
333
334 CallCountingCanvas canvas;
335 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
336 rasterizeCanvasBuffer(buffer, &canvas);
337 EXPECT_EQ(1, canvas.drawOvalCount);
338 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
339}
340
341TEST(CanvasOp, simpleDrawOval) {
342 CanvasOpBuffer buffer;
343 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800344 buffer.push<Op::DrawOval> ({
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800345 .oval = SkRect::MakeEmpty(),
346 .paint = SkPaint{}
347 });
348
349 CallCountingCanvas canvas;
350 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
351 rasterizeCanvasBuffer(buffer, &canvas);
352 EXPECT_EQ(1, canvas.drawOvalCount);
353 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
354}
355
356TEST(CanvasOp, simpleDrawArc) {
357 CanvasOpBuffer buffer;
358 EXPECT_EQ(buffer.size(), 0);
Nader Jawadda9248c2020-11-09 17:27:36 -0800359 buffer.push<Op::DrawArc>({
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800360 .oval = SkRect::MakeWH(100, 100),
361 .startAngle = 120,
362 .sweepAngle = 70,
363 .useCenter = true,
364 .paint = SkPaint{}
365 });
366
367 CallCountingCanvas canvas;
368 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
369 rasterizeCanvasBuffer(buffer, &canvas);
370 EXPECT_EQ(1, canvas.drawArcCount);
371 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
372}
373
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800374TEST(CanvasOp, simpleDrawPath) {
375 CanvasOpBuffer buffer;
376 EXPECT_EQ(buffer.size(), 0);
377 SkPath path;
378 path.addCircle(50, 50, 30);
Nader Jawadda9248c2020-11-09 17:27:36 -0800379 buffer.push<Op::DrawPath> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800380 .path = path,
381 .paint = SkPaint{}
382 });
383
384 CallCountingCanvas canvas;
385 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
386 rasterizeCanvasBuffer(buffer, &canvas);
387 EXPECT_EQ(1, canvas.drawPathCount);
388 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
389}
390
Nader Jawadde3ce842020-11-06 16:54:48 -0800391TEST(CanvasOp, simpleDrawRoundRectProperty) {
392 CanvasOpBuffer buffer;
393 EXPECT_EQ(buffer.size(), 0);
394
395 auto left = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(1));
396 auto top = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(2));
397 auto right = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(3));
398 auto bottom = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(4));
399 auto radiusX = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(5));
400 auto radiusY = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(6));
401 auto propertyPaint =
402 sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));
403
Nader Jawadda9248c2020-11-09 17:27:36 -0800404 buffer.push<Op::DrawRoundRectProperty> ({
Nader Jawadde3ce842020-11-06 16:54:48 -0800405 .left = left,
406 .top = top,
407 .right = right,
408 .bottom = bottom,
409 .rx = radiusX,
410 .ry = radiusY,
411 .paint = propertyPaint
412 });
413
414 CallCountingCanvas canvas;
415 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
416 rasterizeCanvasBuffer(buffer, &canvas);
417 EXPECT_EQ(1, canvas.drawRRectCount);
418 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
419}
420
421TEST(CanvasOp, simpleDrawCircleProperty) {
422 CanvasOpBuffer buffer;
423 EXPECT_EQ(buffer.size(), 0);
424
425 auto x = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(1));
426 auto y = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(2));
427 auto radius = sp<CanvasPropertyPrimitive>(new uirenderer::CanvasPropertyPrimitive(5));
428 auto propertyPaint =
429 sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));
430
Nader Jawadda9248c2020-11-09 17:27:36 -0800431 buffer.push<Op::DrawCircleProperty> ({
Nader Jawadde3ce842020-11-06 16:54:48 -0800432 .x = x,
433 .y = y,
434 .radius = radius,
435 .paint = propertyPaint
436 });
437
438 CallCountingCanvas canvas;
439 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
440 rasterizeCanvasBuffer(buffer, &canvas);
441 EXPECT_EQ(1, canvas.drawOvalCount);
442 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
443}
444
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800445TEST(CanvasOp, simpleDrawVertices) {
446 CanvasOpBuffer buffer;
447 EXPECT_EQ(buffer.size(), 0);
448
449 SkPoint pts[3] = {{64, 32}, {0, 224}, {128, 224}};
450 SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
451 sk_sp<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts,
452 nullptr, colors);
Nader Jawadda9248c2020-11-09 17:27:36 -0800453 buffer.push<Op::DrawVertices> ({
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800454 .vertices = vertices,
455 .mode = SkBlendMode::kSrcOver,
456 .paint = SkPaint{}
457 });
458
459 CallCountingCanvas canvas;
460 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
461 rasterizeCanvasBuffer(buffer, &canvas);
462 EXPECT_EQ(1, canvas.drawVerticesCount);
463 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
464}
465
Nader Jawadda9248c2020-11-09 17:27:36 -0800466TEST(CanvasOp, simpleDrawImage) {
467 CanvasOpBuffer buffer;
468 EXPECT_EQ(buffer.size(), 0);
469
470 SkImageInfo info =SkImageInfo::Make(5, 1,
471 kGray_8_SkColorType, kOpaque_SkAlphaType);
472 sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
473 buffer.push<Op::DrawImage> ({
474 bitmap,
475 7,
476 19,
477 SkPaint{}
478 }
479 );
480
481 CallCountingCanvas canvas;
482 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
483 rasterizeCanvasBuffer(buffer, &canvas);
484 EXPECT_EQ(1, canvas.drawImageCount);
485 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
486}
487
488TEST(CanvasOp, simpleDrawImageRect) {
489 CanvasOpBuffer buffer;
490 EXPECT_EQ(buffer.size(), 0);
491
492 SkImageInfo info = SkImageInfo::Make(5, 1,
493 kGray_8_SkColorType, kOpaque_SkAlphaType);
494
495 sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
496 buffer.push<Op::DrawImageRect> ({
497 bitmap, SkRect::MakeWH(100, 100),
498 SkRect::MakeLTRB(120, 110, 220, 210),
499 SkPaint{}
500 }
501 );
502
503 CallCountingCanvas canvas;
504 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
505 rasterizeCanvasBuffer(buffer, &canvas);
506 EXPECT_EQ(1, canvas.drawImageRectCount);
507 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
508}
509
510TEST(CanvasOp, simpleDrawImageLattice) {
511 CanvasOpBuffer buffer;
512 EXPECT_EQ(buffer.size(), 0);
513
514 SkBitmap skBitmap;
515 skBitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
516
517 const int xDivs[] = { 20, 50 };
518 const int yDivs[] = { 10, 40 };
519 SkCanvas::Lattice::RectType fillTypes[3][3];
520 memset(fillTypes, 0, sizeof(fillTypes));
521 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
522 SkColor colors[9];
523 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], 2,
524 2, nullptr, colors };
525 sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(&skBitmap);
526 buffer.push<Op::DrawImageLattice>(
527 {
528 bitmap,
529 SkRect::MakeWH(5, 1),
530 lattice,
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500531 SkFilterMode::kNearest,
Nader Jawadda9248c2020-11-09 17:27:36 -0800532 SkPaint{}
533 }
534 );
535
536 CallCountingCanvas canvas;
537 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
538 rasterizeCanvasBuffer(buffer, &canvas);
539 EXPECT_EQ(1, canvas.drawImageLatticeCount);
540 EXPECT_EQ(1, canvas.sumTotalDrawCalls());
541}
542
543TEST(CanvasOp, simpleDrawPicture) {
544 CanvasOpBuffer buffer;
545 EXPECT_EQ(buffer.size(), 0);
546
547 SkPictureRecorder recorder;
548 SkCanvas* pictureCanvas = recorder.beginRecording({64, 64, 192, 192});
549 SkPaint paint;
550 pictureCanvas->drawRect(SkRect::MakeWH(200, 200), paint);
551 paint.setColor(SK_ColorWHITE);
552 pictureCanvas->drawRect(SkRect::MakeLTRB(20, 20, 180, 180), paint);
553 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
554 buffer.push<Op::DrawPicture> ({
555 .picture = picture
556 });
557
558 CallCountingCanvas canvas;
559 EXPECT_EQ(0, canvas.sumTotalDrawCalls());
560 rasterizeCanvasBuffer(buffer, &canvas);
561 // Note because we are explicitly issuing 2 drawRect calls
562 // in the picture recorder above, when it is played back into
563 // CallCountingCanvas we will see 2 calls to drawRect instead of 1
564 // call to drawPicture.
565 // This is because SkiaCanvas::drawPicture uses picture.playback(canvas)
566 // instead of canvas->drawPicture.
567 EXPECT_EQ(2, canvas.drawRectCount);
568 EXPECT_EQ(2, canvas.sumTotalDrawCalls());
569}
570
John Reck013127b2020-10-29 20:53:51 -0400571TEST(CanvasOp, immediateRendering) {
572 auto canvas = std::make_shared<CallCountingCanvas>();
573
574 EXPECT_EQ(0, canvas->sumTotalDrawCalls());
575 ImmediateModeRasterizer rasterizer{canvas};
576 auto op = CanvasOp<Op::DrawRect> {
577 .paint = SkPaint{},
578 .rect = SkRect::MakeEmpty()
579 };
580 EXPECT_TRUE(CanvasOpTraits::can_draw<decltype(op)>);
581 rasterizer.draw(op);
582 EXPECT_EQ(1, canvas->drawRectCount);
583 EXPECT_EQ(1, canvas->sumTotalDrawCalls());
John Reckdc95f102020-11-16 12:35:02 -0500584}
585
586TEST(CanvasOp, frontendSaveCount) {
587 SkNoDrawCanvas skiaCanvas(100, 100);
588 CanvasFrontend<CanvasOpCountingReceiver> opCanvas(100, 100);
589 const auto& receiver = opCanvas.receiver();
590
591 EXPECT_EQ(1, skiaCanvas.getSaveCount());
592 EXPECT_EQ(1, opCanvas.saveCount());
593
594 skiaCanvas.save();
595 opCanvas.save(SaveFlags::MatrixClip);
596 EXPECT_EQ(2, skiaCanvas.getSaveCount());
597 EXPECT_EQ(2, opCanvas.saveCount());
598
599 skiaCanvas.restore();
600 opCanvas.restore();
601 EXPECT_EQ(1, skiaCanvas.getSaveCount());
602 EXPECT_EQ(1, opCanvas.saveCount());
603
604 skiaCanvas.restore();
605 opCanvas.restore();
606 EXPECT_EQ(1, skiaCanvas.getSaveCount());
607 EXPECT_EQ(1, opCanvas.saveCount());
608
609 EXPECT_EQ(1, receiver[Op::Save]);
610 EXPECT_EQ(1, receiver[Op::Restore]);
611}