Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2274)

Side by Side Diff: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DUsageTrackingTest.cpp

Issue 2903053002: Removing canvas rendering mode switching feature (Closed)
Patch Set: fix test failure Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/canvas2d/CanvasRenderingContext2D.h"
6
7 #include "bindings/core/v8/V8BindingForCore.h"
8 #include "core/dom/Document.h"
9 #include "core/frame/FrameView.h"
10 #include "core/frame/Settings.h"
11 #include "core/html/HTMLCanvasElement.h"
12 #include "core/html/ImageData.h"
13 #include "core/loader/EmptyClients.h"
14 #include "core/testing/DummyPageHolder.h"
15 #include "modules/accessibility/AXObjectCacheImpl.h"
16 #include "modules/canvas2d/CanvasGradient.h"
17 #include "modules/canvas2d/CanvasPattern.h"
18 #include "modules/canvas2d/HitRegionOptions.h"
19 #include "modules/canvas2d/Path2D.h"
20 #include "modules/webgl/WebGLRenderingContext.h"
21 #include "platform/RuntimeEnabledFeatures.h"
22 #include "platform/graphics/StaticBitmapImage.h"
23 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
24 #include "platform/loader/fetch/MemoryCache.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/skia/include/core/SkSurface.h"
28
29 using ::testing::Mock;
30
31 namespace blink {
32 namespace UsageTrackingTests {
33
34 enum BitmapOpacity { kOpaqueBitmap, kTransparentBitmap };
35
36 class FakeImageSource : public CanvasImageSource {
37 public:
38 FakeImageSource(IntSize, BitmapOpacity);
39
40 PassRefPtr<Image> GetSourceImageForCanvas(SourceImageStatus*,
41 AccelerationHint,
42 SnapshotReason,
43 const FloatSize&) override;
44
45 bool WouldTaintOrigin(
46 SecurityOrigin* destination_security_origin) const override {
47 return false;
48 }
49 FloatSize ElementSize(const FloatSize&) const override {
50 return FloatSize(size_);
51 }
52 bool IsOpaque() const override { return is_opaque_; }
53 bool IsAccelerated() const override { return false; }
54 int SourceWidth() override { return size_.Width(); }
55 int SourceHeight() override { return size_.Height(); }
56
57 ~FakeImageSource() override {}
58
59 private:
60 IntSize size_;
61 RefPtr<Image> image_;
62 bool is_opaque_;
63 };
64
65 FakeImageSource::FakeImageSource(IntSize size, BitmapOpacity opacity)
66 : size_(size), is_opaque_(opacity == kOpaqueBitmap) {
67 sk_sp<SkSurface> surface(
68 SkSurface::MakeRasterN32Premul(size_.Width(), size_.Height()));
69 surface->getCanvas()->clear(opacity == kOpaqueBitmap ? SK_ColorWHITE
70 : SK_ColorTRANSPARENT);
71 image_ = StaticBitmapImage::Create(surface->makeImageSnapshot());
72 }
73
74 PassRefPtr<Image> FakeImageSource::GetSourceImageForCanvas(
75 SourceImageStatus* status,
76 AccelerationHint,
77 SnapshotReason,
78 const FloatSize&) {
79 if (status)
80 *status = kNormalSourceImageStatus;
81 return image_;
82 }
83
84 class CanvasRenderingContextUsageTrackingTest : public ::testing::Test {
85 protected:
86 CanvasRenderingContextUsageTrackingTest();
87 void SetUp() override;
88
89 DummyPageHolder& Page() const { return *dummy_page_holder_; }
90 Document& GetDocument() const { return *document_; }
91 HTMLCanvasElement& CanvasElement() const { return *canvas_element_; }
92 CanvasRenderingContext2D* Context2d() const;
93
94 void CreateContext(OpacityMode);
95
96 FakeImageSource opaque_bitmap_;
97 FakeImageSource alpha_bitmap_;
98 Persistent<ImageData> full_image_data_;
99 void TearDown();
100
101 ScriptState* GetScriptState() {
102 return ToScriptStateForMainWorld(canvas_element_->GetFrame());
103 }
104
105 private:
106 std::shared_ptr<DummyPageHolder> dummy_page_holder_;
107 Persistent<Document> document_;
108 Persistent<HTMLCanvasElement> canvas_element_;
109 Persistent<MemoryCache> global_memory_cache_;
110 };
111
112 CanvasRenderingContextUsageTrackingTest::
113 CanvasRenderingContextUsageTrackingTest()
114 : opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap),
115 alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {}
116
117 void CanvasRenderingContextUsageTrackingTest::TearDown() {
118 ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack,
119 BlinkGC::kGCWithSweep,
120 BlinkGC::kForcedGC);
121 ReplaceMemoryCacheForTesting(global_memory_cache_.Release());
122 }
123
124 CanvasRenderingContext2D* CanvasRenderingContextUsageTrackingTest::Context2d()
125 const {
126 // If the following check fails, perhaps you forgot to call createContext
127 // in your test?
128 EXPECT_NE(nullptr, CanvasElement().RenderingContext());
129 EXPECT_TRUE(CanvasElement().RenderingContext()->Is2d());
130 return static_cast<CanvasRenderingContext2D*>(
131 CanvasElement().RenderingContext());
132 }
133
134 void CanvasRenderingContextUsageTrackingTest::CreateContext(
135 OpacityMode opacity_mode) {
136 String canvas_type("2d");
137 CanvasContextCreationAttributes attributes;
138 attributes.setAlpha(opacity_mode == kNonOpaque);
139 canvas_element_->GetCanvasRenderingContext(canvas_type, attributes);
140 Context2d(); // Calling this for the checks
141 }
142
143 void CanvasRenderingContextUsageTrackingTest::SetUp() {
144 Page::PageClients page_clients;
145 FillWithEmptyClients(page_clients);
146 dummy_page_holder_ =
147 DummyPageHolder::Create(IntSize(800, 600), &page_clients);
148 document_ = &dummy_page_holder_->GetDocument();
149 document_->documentElement()->setInnerHTML(
150 "<body><canvas id='c'></canvas></body>");
151 document_->View()->UpdateAllLifecyclePhases();
152 canvas_element_ = toHTMLCanvasElement(document_->getElementById("c"));
153 full_image_data_ = ImageData::Create(IntSize(10, 10));
154
155 global_memory_cache_ = ReplaceMemoryCacheForTesting(MemoryCache::Create());
156
157 RuntimeEnabledFeatures::setEnableCanvas2dDynamicRenderingModeSwitchingEnabled(
158 true);
159 }
160
161 TEST_F(CanvasRenderingContextUsageTrackingTest, FillTracking) {
162 CreateContext(kNonOpaque);
163
164 int num_reps = 100;
165 for (int i = 0; i < num_reps; i++) {
166 Context2d()->beginPath();
167 Context2d()->moveTo(1, 1);
168 Context2d()->lineTo(4, 1);
169 Context2d()->lineTo(4, 4);
170 Context2d()->lineTo(2, 2);
171 Context2d()->lineTo(1, 4);
172 Context2d()->fill(); // path is not convex
173
174 Context2d()->fillText("Hello World!!!", 10, 10, 1);
175 Context2d()->fillRect(10, 10, 100, 100);
176 Context2d()->fillText("Hello World!!!", 10, 10);
177
178 Context2d()->beginPath();
179 Context2d()->moveTo(1, 1);
180 Context2d()->lineTo(4, 1);
181 Context2d()->lineTo(4, 4);
182 Context2d()->lineTo(1, 4);
183 Context2d()->fill(); // path is convex
184
185 Context2d()->fillRect(10, 10, 100, 100);
186 }
187
188 EXPECT_EQ(num_reps * 2,
189 Context2d()
190 ->GetUsage()
191 .num_draw_calls[BaseRenderingContext2D::kFillPath]);
192 EXPECT_EQ(num_reps * 2,
193 Context2d()
194 ->GetUsage()
195 .num_draw_calls[BaseRenderingContext2D::kFillRect]);
196 EXPECT_EQ(num_reps, Context2d()->GetUsage().num_non_convex_fill_path_calls);
197 EXPECT_EQ(num_reps * 2,
198 Context2d()
199 ->GetUsage()
200 .num_draw_calls[BaseRenderingContext2D::kFillText]);
201
202 // areas
203 EXPECT_NEAR(
204 static_cast<double>(num_reps * (100 * 100) * 2),
205 Context2d()
206 ->GetUsage()
207 .bounding_box_area_draw_calls[BaseRenderingContext2D::kFillRect],
208 1.0);
209 EXPECT_NEAR(
210 static_cast<double>(num_reps * (2 * 100 + 2 * 100) * 2),
211 Context2d()
212 ->GetUsage()
213 .bounding_box_perimeter_draw_calls[BaseRenderingContext2D::kFillRect],
214 1.0);
215
216 EXPECT_TRUE(
217 static_cast<double>(num_reps * (100 * 100) * 2) <
218 Context2d()
219 ->GetUsage()
220 .bounding_box_area_fill_type[BaseRenderingContext2D::kColorFillType]);
221 EXPECT_TRUE(
222 static_cast<double>(num_reps * (100 * 100) * 2) * 1.1 >
223 Context2d()
224 ->GetUsage()
225 .bounding_box_area_fill_type[BaseRenderingContext2D::kColorFillType]);
226
227 EXPECT_NEAR(
228 static_cast<double>(num_reps * (3 * 3) * 2),
229 Context2d()
230 ->GetUsage()
231 .bounding_box_area_draw_calls[BaseRenderingContext2D::kFillPath],
232 1.0);
233 EXPECT_NEAR(
234 static_cast<double>(num_reps * (2 * 3 + 2 * 3) * 2),
235 Context2d()
236 ->GetUsage()
237 .bounding_box_perimeter_draw_calls[BaseRenderingContext2D::kFillPath],
238 1.0);
239
240 EXPECT_TRUE(Context2d()->GetUsage().bounding_box_perimeter_draw_calls
241 [BaseRenderingContext2D::kFillText] > 0.0);
242 EXPECT_TRUE(Context2d()->GetUsage().bounding_box_perimeter_draw_calls
243 [BaseRenderingContext2D::kStrokeText] == 0.0);
244
245 // create gradient
246 CanvasGradient* gradient;
247 gradient = Context2d()->createLinearGradient(0, 0, 100, 100);
248 Context2d()->setFillStyle(
249 StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient));
250 Context2d()->fillRect(10, 10, 100, 20);
251 EXPECT_EQ(1, Context2d()->GetUsage().num_linear_gradients);
252 EXPECT_NEAR(100 * 20,
253 Context2d()->GetUsage().bounding_box_area_fill_type
254 [BaseRenderingContext2D::kLinearGradientFillType],
255 1.0);
256
257 NonThrowableExceptionState exception_state;
258 gradient = Context2d()->createRadialGradient(0, 0, 100, 100, 200, 200,
259 exception_state);
260 Context2d()->setFillStyle(
261 StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient));
262 Context2d()->fillRect(10, 10, 100, 20);
263 EXPECT_EQ(1, Context2d()->GetUsage().num_linear_gradients);
264 EXPECT_EQ(1, Context2d()->GetUsage().num_radial_gradients);
265 EXPECT_NEAR(100 * 20,
266 Context2d()->GetUsage().bounding_box_area_fill_type
267 [BaseRenderingContext2D::kRadialGradientFillType],
268 1.0);
269
270 // create pattern
271 NonThrowableExceptionState exception_state2;
272 CanvasPattern* canvas_pattern = Context2d()->createPattern(
273 GetScriptState(), &opaque_bitmap_, "repeat-x", exception_state2);
274 StringOrCanvasGradientOrCanvasPattern pattern =
275 StringOrCanvasGradientOrCanvasPattern::fromCanvasPattern(canvas_pattern);
276 Context2d()->setFillStyle(pattern);
277 Context2d()->fillRect(10, 10, 200, 100);
278 EXPECT_EQ(1, Context2d()->GetUsage().num_patterns);
279 EXPECT_NEAR(200 * 100,
280 Context2d()->GetUsage().bounding_box_area_fill_type
281 [BaseRenderingContext2D::kPatternFillType],
282 1.0);
283
284 // Other fill method
285 Context2d()->fill(Path2D::Create("Hello World!!!"));
286 EXPECT_EQ(num_reps * 2 + 1,
287 Context2d()
288 ->GetUsage()
289 .num_draw_calls[BaseRenderingContext2D::kFillPath]);
290
291 EXPECT_EQ(0, Context2d()
292 ->GetUsage()
293 .num_draw_calls[BaseRenderingContext2D::kStrokePath]);
294 EXPECT_EQ(0, Context2d()
295 ->GetUsage()
296 .num_draw_calls[BaseRenderingContext2D::kStrokeText]);
297 EXPECT_EQ(0, Context2d()->GetUsage().num_put_image_data_calls);
298 EXPECT_EQ(0, Context2d()
299 ->GetUsage()
300 .num_draw_calls[BaseRenderingContext2D::kDrawVectorImage]);
301 EXPECT_EQ(0, Context2d()
302 ->GetUsage()
303 .num_draw_calls[BaseRenderingContext2D::kDrawBitmapImage]);
304 EXPECT_EQ(0, Context2d()->GetUsage().num_get_image_data_calls);
305 }
306
307 TEST_F(CanvasRenderingContextUsageTrackingTest, StrokeTracking) {
308 CreateContext(kNonOpaque);
309
310 int num_reps = 100;
311 for (int i = 0; i < num_reps; i++) {
312 Context2d()->strokeRect(10, 10, 100, 100);
313
314 Context2d()->beginPath();
315 Context2d()->moveTo(1, 1);
316 Context2d()->lineTo(4, 1);
317 Context2d()->lineTo(4, 4);
318 Context2d()->lineTo(2, 2);
319 Context2d()->lineTo(1, 4);
320 Context2d()->stroke();
321
322 Context2d()->strokeText("Hello World!!!", 10, 10, 1);
323
324 Context2d()->strokeRect(10, 10, 100, 100);
325 Context2d()->strokeText("Hello World!!!", 10, 10);
326 }
327
328 EXPECT_EQ(num_reps, Context2d()
329 ->GetUsage()
330 .num_draw_calls[BaseRenderingContext2D::kStrokePath]);
331 EXPECT_EQ(num_reps * 2,
332 Context2d()
333 ->GetUsage()
334 .num_draw_calls[BaseRenderingContext2D::kStrokeRect]);
335 EXPECT_EQ(num_reps * 2,
336 Context2d()
337 ->GetUsage()
338 .num_draw_calls[BaseRenderingContext2D::kStrokeText]);
339
340 EXPECT_NEAR(
341 static_cast<double>(num_reps * (100 * 100) * 2),
342 Context2d()
343 ->GetUsage()
344 .bounding_box_area_draw_calls[BaseRenderingContext2D::kStrokeRect],
345 1.0);
346 EXPECT_NEAR(static_cast<double>(num_reps * (2 * 100 + 2 * 100) * 2),
347 Context2d()->GetUsage().bounding_box_perimeter_draw_calls
348 [BaseRenderingContext2D::kStrokeRect],
349 1.0);
350 EXPECT_NEAR(
351 static_cast<double>(num_reps * (3 * 3)),
352 Context2d()
353 ->GetUsage()
354 .bounding_box_area_draw_calls[BaseRenderingContext2D::kStrokePath],
355 1.0);
356 EXPECT_NEAR(static_cast<double>(num_reps * (2 * 3 + 2 * 3)),
357 Context2d()->GetUsage().bounding_box_perimeter_draw_calls
358 [BaseRenderingContext2D::kStrokePath],
359 1.0);
360
361 // create gradient
362 CanvasGradient* gradient;
363 gradient = Context2d()->createLinearGradient(0, 0, 100, 100);
364 Context2d()->setStrokeStyle(
365 StringOrCanvasGradientOrCanvasPattern::fromCanvasGradient(gradient));
366 Context2d()->strokeRect(10, 10, 100, 100);
367 EXPECT_EQ(1, Context2d()->GetUsage().num_linear_gradients);
368 EXPECT_NEAR(100 * 100,
369 Context2d()->GetUsage().bounding_box_area_fill_type
370 [BaseRenderingContext2D::kLinearGradientFillType],
371 1.0);
372
373 // create pattern
374 NonThrowableExceptionState exception_state;
375 CanvasPattern* canvas_pattern = Context2d()->createPattern(
376 GetScriptState(), &opaque_bitmap_, "repeat-x", exception_state);
377 StringOrCanvasGradientOrCanvasPattern pattern =
378 StringOrCanvasGradientOrCanvasPattern::fromCanvasPattern(canvas_pattern);
379 Context2d()->setStrokeStyle(pattern);
380 Context2d()->strokeRect(10, 10, 100, 100);
381 EXPECT_EQ(1, Context2d()->GetUsage().num_patterns);
382 EXPECT_NEAR(100 * 100,
383 Context2d()->GetUsage().bounding_box_area_fill_type
384 [BaseRenderingContext2D::kPatternFillType],
385 1.0);
386
387 // Other stroke method
388 Context2d()->stroke(Path2D::Create("Hello World!!!"));
389 EXPECT_EQ(num_reps + 1,
390 Context2d()
391 ->GetUsage()
392 .num_draw_calls[BaseRenderingContext2D::kStrokePath]);
393 EXPECT_EQ(0, Context2d()
394 ->GetUsage()
395 .num_draw_calls[BaseRenderingContext2D::kFillPath]);
396 EXPECT_EQ(0, Context2d()->GetUsage().num_non_convex_fill_path_calls);
397 EXPECT_EQ(0, Context2d()
398 ->GetUsage()
399 .num_draw_calls[BaseRenderingContext2D::kFillText]);
400 EXPECT_EQ(0, Context2d()->GetUsage().num_put_image_data_calls);
401 EXPECT_EQ(0, Context2d()
402 ->GetUsage()
403 .num_draw_calls[BaseRenderingContext2D::kDrawVectorImage]);
404 EXPECT_EQ(0, Context2d()
405 ->GetUsage()
406 .num_draw_calls[BaseRenderingContext2D::kDrawBitmapImage]);
407 EXPECT_EQ(0, Context2d()->GetUsage().num_get_image_data_calls);
408 }
409
410 TEST_F(CanvasRenderingContextUsageTrackingTest, ImageTracking) {
411 // Testing draw, put, get and filters
412 CreateContext(kNonOpaque);
413 NonThrowableExceptionState exception_state;
414
415 int num_reps = 5;
416 int img_width = 100;
417 int img_height = 200;
418 for (int i = 0; i < num_reps; i++) {
419 Context2d()->putImageData(full_image_data_.Get(), 0, 0, exception_state);
420 Context2d()->drawImage(GetScriptState(), &opaque_bitmap_, 0, 0, 1, 1, 0, 0,
421 img_width, img_height, exception_state);
422 Context2d()->getImageData(0, 0, 10, 100, exception_state);
423 }
424
425 EXPECT_NEAR(num_reps * img_width * img_height,
426 Context2d()->GetUsage().bounding_box_area_draw_calls
427 [BaseRenderingContext2D::kDrawBitmapImage],
428 0.1);
429 EXPECT_NEAR(num_reps * (2 * img_width + 2 * img_height),
430 Context2d()->GetUsage().bounding_box_perimeter_draw_calls
431 [BaseRenderingContext2D::kDrawBitmapImage],
432 0.1);
433
434 EXPECT_NEAR(0.0,
435 Context2d()->GetUsage().bounding_box_area_draw_calls
436 [BaseRenderingContext2D::kDrawVectorImage],
437 0.1);
438 EXPECT_NEAR(0.0,
439 Context2d()->GetUsage().bounding_box_perimeter_draw_calls
440 [BaseRenderingContext2D::kDrawVectorImage],
441 0.1);
442
443 Context2d()->setFilter("blur(5px)");
444 Context2d()->drawImage(GetScriptState(), &opaque_bitmap_, 0, 0, 1, 1, 0, 0,
445 10, 10, exception_state);
446
447 EXPECT_EQ(num_reps, Context2d()->GetUsage().num_put_image_data_calls);
448 EXPECT_NE(0, Context2d()->GetUsage().area_put_image_data_calls);
449 EXPECT_NEAR(num_reps * full_image_data_.Get()->width() *
450 full_image_data_.Get()->height(),
451 Context2d()->GetUsage().area_put_image_data_calls, 0.1);
452
453 EXPECT_EQ(num_reps + 1,
454 Context2d()
455 ->GetUsage()
456 .num_draw_calls[BaseRenderingContext2D::kDrawBitmapImage]);
457 EXPECT_EQ(num_reps, Context2d()->GetUsage().num_get_image_data_calls);
458
459 EXPECT_EQ(1, Context2d()->GetUsage().num_filters);
460 EXPECT_NEAR(num_reps * 10 * 100,
461 Context2d()->GetUsage().area_get_image_data_calls, 0.1);
462
463 EXPECT_EQ(0, Context2d()
464 ->GetUsage()
465 .num_draw_calls[BaseRenderingContext2D::kFillPath]);
466 EXPECT_EQ(0, Context2d()->GetUsage().num_non_convex_fill_path_calls);
467 EXPECT_EQ(0, Context2d()
468 ->GetUsage()
469 .num_draw_calls[BaseRenderingContext2D::kFillText]);
470 EXPECT_EQ(0, Context2d()
471 ->GetUsage()
472 .num_draw_calls[BaseRenderingContext2D::kStrokePath]);
473 EXPECT_EQ(0, Context2d()
474 ->GetUsage()
475 .num_draw_calls[BaseRenderingContext2D::kStrokeText]);
476 }
477
478 TEST_F(CanvasRenderingContextUsageTrackingTest, ClearRectTracking) {
479 CreateContext(kNonOpaque);
480 Context2d()->clearRect(0, 0, 1, 1);
481 Context2d()->clearRect(0, 0, 2, 2);
482 EXPECT_EQ(2, Context2d()->GetUsage().num_clear_rect_calls);
483
484 EXPECT_EQ(0, Context2d()
485 ->GetUsage()
486 .num_draw_calls[BaseRenderingContext2D::kFillPath]);
487 EXPECT_EQ(0, Context2d()->GetUsage().num_non_convex_fill_path_calls);
488 EXPECT_EQ(0, Context2d()
489 ->GetUsage()
490 .num_draw_calls[BaseRenderingContext2D::kFillText]);
491 EXPECT_EQ(0, Context2d()
492 ->GetUsage()
493 .num_draw_calls[BaseRenderingContext2D::kStrokePath]);
494 EXPECT_EQ(0, Context2d()
495 ->GetUsage()
496 .num_draw_calls[BaseRenderingContext2D::kStrokeText]);
497 }
498
499 TEST_F(CanvasRenderingContextUsageTrackingTest, ComplexClipsTracking) {
500 CreateContext(kNonOpaque);
501 Context2d()->save();
502
503 // simple clip
504 Context2d()->beginPath();
505 Context2d()->moveTo(1, 1);
506 Context2d()->lineTo(4, 1);
507 Context2d()->lineTo(4, 4);
508 Context2d()->lineTo(1, 4);
509 Context2d()->clip("nonzero");
510 Context2d()->fillRect(0, 0, 1, 1);
511 EXPECT_EQ(0, Context2d()->GetUsage().num_draw_with_complex_clips);
512
513 // complex clips
514 int num_reps = 5;
515 for (int i = 0; i < num_reps; i++) {
516 Context2d()->beginPath();
517 Context2d()->moveTo(1, 1);
518 Context2d()->lineTo(4, 1);
519 Context2d()->lineTo(4, 4);
520 Context2d()->lineTo(2, 2);
521 Context2d()->lineTo(1, 4);
522 Context2d()->clip("nonzero");
523 Context2d()->fillRect(0, 0, 1, 1);
524 }
525
526 // remove all previous clips
527 Context2d()->restore();
528
529 // simple clip again
530 Context2d()->beginPath();
531 Context2d()->moveTo(1, 1);
532 Context2d()->lineTo(4, 1);
533 Context2d()->lineTo(4, 4);
534 Context2d()->lineTo(1, 4);
535 Context2d()->clip("nonzero");
536 Context2d()->fillRect(0, 0, 1, 1);
537
538 EXPECT_EQ(num_reps, Context2d()->GetUsage().num_draw_with_complex_clips);
539 }
540
541 TEST_F(CanvasRenderingContextUsageTrackingTest, ShadowsTracking) {
542 CreateContext(kNonOpaque);
543
544 Context2d()->beginPath();
545 Context2d()->fillRect(0, 0, 1, 1);
546
547 // shadow with blur = 0
548 Context2d()->beginPath();
549 Context2d()->setShadowBlur(0.0);
550 Context2d()->setShadowColor("rgba(255, 0, 0, 0.5)");
551 Context2d()->setShadowOffsetX(1.0);
552 Context2d()->setShadowOffsetY(1.0);
553 Context2d()->fillRect(0, 0, 1, 1);
554
555 // shadow with alpha = 0
556 Context2d()->beginPath();
557 Context2d()->setShadowBlur(0.5);
558 Context2d()->setShadowColor("rgba(255, 0, 0, 0)");
559 Context2d()->setShadowOffsetX(1.0);
560 Context2d()->setShadowOffsetY(1.0);
561 Context2d()->fillRect(0, 0, 1, 1);
562
563 EXPECT_EQ(0, Context2d()->GetUsage().num_blurred_shadows);
564 EXPECT_NEAR(
565 0.0, Context2d()->GetUsage().bounding_box_area_times_shadow_blur_squared,
566 0.1);
567 EXPECT_NEAR(
568 0.0,
569 Context2d()->GetUsage().bounding_box_perimeter_times_shadow_blur_squared,
570 0.1);
571
572 int num_reps = 5;
573 double shadow_blur = 0.5;
574 for (int i = 0; i < num_reps; i++) {
575 Context2d()->beginPath();
576 Context2d()->setShadowBlur(shadow_blur);
577 Context2d()->setShadowColor("rgba(255, 0, 0, 0.5)");
578 Context2d()->setShadowOffsetX(1.0);
579 Context2d()->setShadowOffsetY(1.0);
580 Context2d()->fillRect(0, 0, 3, 10);
581 }
582 EXPECT_EQ(num_reps, Context2d()->GetUsage().num_blurred_shadows);
583
584 double area_times_shadow_blur_squared =
585 shadow_blur * shadow_blur * num_reps * 3 * 10;
586 double perimeter_times_shadow_blur_squared =
587 shadow_blur * shadow_blur * num_reps * (2 * 3 + 2 * 10);
588 EXPECT_NEAR(
589 area_times_shadow_blur_squared,
590 Context2d()->GetUsage().bounding_box_area_times_shadow_blur_squared, 0.1);
591 EXPECT_NEAR(
592 perimeter_times_shadow_blur_squared,
593 Context2d()->GetUsage().bounding_box_perimeter_times_shadow_blur_squared,
594 0.1);
595
596 double shadow_blur2 = 4.5;
597 Context2d()->beginPath();
598 Context2d()->setShadowBlur(shadow_blur2);
599 Context2d()->moveTo(1, 1);
600 Context2d()->lineTo(4, 1);
601 Context2d()->lineTo(4, 4);
602 Context2d()->lineTo(2, 2);
603 Context2d()->lineTo(1, 4);
604 Context2d()->fill();
605
606 area_times_shadow_blur_squared += 3.0 * 3.0 * shadow_blur2 * shadow_blur2;
607 perimeter_times_shadow_blur_squared +=
608 (2 * 3 + 2 * 3) * shadow_blur2 * shadow_blur2;
609 EXPECT_NEAR(
610 area_times_shadow_blur_squared,
611 Context2d()->GetUsage().bounding_box_area_times_shadow_blur_squared, 0.1);
612 EXPECT_NEAR(
613 perimeter_times_shadow_blur_squared,
614 Context2d()->GetUsage().bounding_box_perimeter_times_shadow_blur_squared,
615 0.1);
616
617 NonThrowableExceptionState exception_state;
618 int img_width = 100;
619 int img_height = 200;
620 for (int i = 0; i < num_reps; i++) {
621 Context2d()->putImageData(full_image_data_.Get(), 0, 0, exception_state);
622 Context2d()->setShadowBlur(shadow_blur2);
623 Context2d()->drawImage(GetScriptState(), &opaque_bitmap_, 0, 0, 1, 1, 0, 0,
624 img_width, img_height, exception_state);
625 Context2d()->getImageData(0, 0, 1, 1, exception_state);
626 }
627
628 area_times_shadow_blur_squared +=
629 img_width * img_height * shadow_blur2 * shadow_blur2 * num_reps;
630 perimeter_times_shadow_blur_squared +=
631 (2 * img_width + 2 * img_height) * shadow_blur2 * shadow_blur2 * num_reps;
632 EXPECT_NEAR(
633 area_times_shadow_blur_squared,
634 Context2d()->GetUsage().bounding_box_area_times_shadow_blur_squared, 0.1);
635 EXPECT_NEAR(
636 perimeter_times_shadow_blur_squared,
637 Context2d()->GetUsage().bounding_box_perimeter_times_shadow_blur_squared,
638 0.1);
639 }
640
641 TEST_F(CanvasRenderingContextUsageTrackingTest, incrementFrameCount) {
642 CreateContext(kNonOpaque);
643 EXPECT_EQ(0, Context2d()->GetUsage().num_frames_since_reset);
644
645 Context2d()->FinalizeFrame();
646 EXPECT_EQ(1, Context2d()->GetUsage().num_frames_since_reset);
647
648 Context2d()->FinalizeFrame();
649 Context2d()->FinalizeFrame();
650 EXPECT_EQ(3, Context2d()->GetUsage().num_frames_since_reset);
651 }
652
653 TEST_F(CanvasRenderingContextUsageTrackingTest, resetUsageTracking) {
654 CreateContext(kNonOpaque);
655 EXPECT_EQ(0, Context2d()->GetUsage().num_frames_since_reset);
656
657 Context2d()->FinalizeFrame();
658 Context2d()->FinalizeFrame();
659 EXPECT_EQ(2, Context2d()->GetUsage().num_frames_since_reset);
660
661 const int kNumReps = 100;
662 for (int i = 0; i < kNumReps; i++) {
663 Context2d()->fillRect(10, 10, 100, 100);
664 }
665 EXPECT_EQ(kNumReps, Context2d()
666 ->GetUsage()
667 .num_draw_calls[BaseRenderingContext2D::kFillRect]);
668
669 Context2d()->ResetUsageTracking();
670 EXPECT_EQ(0, Context2d()->GetUsage().num_frames_since_reset);
671 EXPECT_EQ(0, Context2d()
672 ->GetUsage()
673 .num_draw_calls[BaseRenderingContext2D::kFillRect]);
674
675 for (int i = 0; i < kNumReps; i++) {
676 Context2d()->fillRect(10, 10, 100, 100);
677 }
678 EXPECT_EQ(kNumReps, Context2d()
679 ->GetUsage()
680 .num_draw_calls[BaseRenderingContext2D::kFillRect]);
681 }
682
683 } // namespace UsageTrackingTests
684 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698