OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/canvas2d/CanvasRenderingContext2D.h" | 5 #include "modules/canvas2d/CanvasRenderingContext2D.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "bindings/core/v8/V8Binding.h" | 8 #include "bindings/core/v8/V8Binding.h" |
9 #include "bindings/core/v8/V8BindingForTesting.h" | 9 #include "bindings/core/v8/V8BindingForTesting.h" |
10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, | 252 std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, |
253 const IntSize& size, | 253 const IntSize& size, |
254 Canvas2DLayerBridge::AccelerationMode acceleration_mode) { | 254 Canvas2DLayerBridge::AccelerationMode acceleration_mode) { |
255 return AdoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, | 255 return AdoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, |
256 kNonOpaque, acceleration_mode, | 256 kNonOpaque, acceleration_mode, |
257 CanvasColorParams())); | 257 CanvasColorParams())); |
258 } | 258 } |
259 | 259 |
260 //============================================================================ | 260 //============================================================================ |
261 | 261 |
262 class FakeAcceleratedImageBufferSurfaceForTesting | 262 class FakeAcceleratedImageBufferSurface |
263 : public UnacceleratedImageBufferSurface { | 263 : public UnacceleratedImageBufferSurface { |
264 public: | 264 public: |
265 FakeAcceleratedImageBufferSurfaceForTesting(const IntSize& size, | 265 FakeAcceleratedImageBufferSurface(const IntSize& size, OpacityMode mode) |
266 OpacityMode mode) | |
267 : UnacceleratedImageBufferSurface(size, mode), is_accelerated_(true) {} | 266 : UnacceleratedImageBufferSurface(size, mode), is_accelerated_(true) {} |
268 ~FakeAcceleratedImageBufferSurfaceForTesting() override {} | 267 ~FakeAcceleratedImageBufferSurface() override {} |
269 bool IsAccelerated() const override { return is_accelerated_; } | 268 bool IsAccelerated() const override { return is_accelerated_; } |
270 void SetIsAccelerated(bool is_accelerated) { | 269 void SetIsAccelerated(bool is_accelerated) { |
271 if (is_accelerated != is_accelerated_) | 270 if (is_accelerated != is_accelerated_) |
272 is_accelerated_ = is_accelerated; | 271 is_accelerated_ = is_accelerated; |
273 } | 272 } |
274 | 273 |
275 private: | 274 private: |
276 bool is_accelerated_; | 275 bool is_accelerated_; |
277 }; | 276 }; |
278 | 277 |
(...skipping 10 matching lines...) Expand all Loading... |
289 return true; | 288 return true; |
290 } // otherwise overwrites are not tracked | 289 } // otherwise overwrites are not tracked |
291 | 290 |
292 MOCK_METHOD0(WillOverwriteCanvas, void()); | 291 MOCK_METHOD0(WillOverwriteCanvas, void()); |
293 }; | 292 }; |
294 | 293 |
295 //============================================================================ | 294 //============================================================================ |
296 | 295 |
297 #define TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ | 296 #define TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ |
298 std::unique_ptr<MockImageBufferSurfaceForOverwriteTesting> mock_surface = \ | 297 std::unique_ptr<MockImageBufferSurfaceForOverwriteTesting> mock_surface = \ |
299 WTF::WrapUnique(new MockImageBufferSurfaceForOverwriteTesting( \ | 298 WTF::MakeUnique<MockImageBufferSurfaceForOverwriteTesting>( \ |
300 IntSize(10, 10), kNonOpaque)); \ | 299 IntSize(10, 10), kNonOpaque); \ |
301 MockImageBufferSurfaceForOverwriteTesting* surface_ptr = mock_surface.get(); \ | 300 MockImageBufferSurfaceForOverwriteTesting* surface_ptr = mock_surface.get(); \ |
302 CanvasElement().CreateImageBufferUsingSurfaceForTesting( \ | 301 CanvasElement().CreateImageBufferUsingSurfaceForTesting( \ |
303 std::move(mock_surface)); \ | 302 std::move(mock_surface)); \ |
304 EXPECT_CALL(*surface_ptr, WillOverwriteCanvas()).Times(EXPECTED_OVERDRAWS); \ | 303 EXPECT_CALL(*surface_ptr, WillOverwriteCanvas()).Times(EXPECTED_OVERDRAWS); \ |
305 Context2d()->save(); | 304 Context2d()->save(); |
306 | 305 |
307 #define TEST_OVERDRAW_FINALIZE \ | 306 #define TEST_OVERDRAW_FINALIZE \ |
308 Context2d()->restore(); \ | 307 Context2d()->restore(); \ |
309 Mock::VerifyAndClearExpectations(surface_ptr); | 308 Mock::VerifyAndClearExpectations(surface_ptr); |
310 | 309 |
(...skipping 26 matching lines...) Expand all Loading... |
337 TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ | 336 TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ |
338 Context2d()->CALL1; \ | 337 Context2d()->CALL1; \ |
339 Context2d()->CALL2; \ | 338 Context2d()->CALL2; \ |
340 Context2d()->CALL3; \ | 339 Context2d()->CALL3; \ |
341 Context2d()->CALL4; \ | 340 Context2d()->CALL4; \ |
342 TEST_OVERDRAW_FINALIZE \ | 341 TEST_OVERDRAW_FINALIZE \ |
343 } while (0) | 342 } while (0) |
344 | 343 |
345 //============================================================================ | 344 //============================================================================ |
346 | 345 |
347 class MockSurfaceFactory : public RecordingImageBufferFallbackSurfaceFactory { | |
348 public: | |
349 enum FallbackExpectation { kExpectFallback, kExpectNoFallback }; | |
350 static std::unique_ptr<MockSurfaceFactory> Create( | |
351 FallbackExpectation expectation) { | |
352 return WTF::WrapUnique(new MockSurfaceFactory(expectation)); | |
353 } | |
354 | |
355 std::unique_ptr<ImageBufferSurface> CreateSurface( | |
356 const IntSize& size, | |
357 OpacityMode mode, | |
358 const CanvasColorParams& color_params) override { | |
359 EXPECT_EQ(kExpectFallback, expectation_); | |
360 did_fallback_ = true; | |
361 return WTF::WrapUnique(new UnacceleratedImageBufferSurface( | |
362 size, mode, kInitializeImagePixels, color_params)); | |
363 } | |
364 | |
365 ~MockSurfaceFactory() override { | |
366 if (expectation_ == kExpectFallback) { | |
367 EXPECT_TRUE(did_fallback_); | |
368 } | |
369 } | |
370 | |
371 private: | |
372 MockSurfaceFactory(FallbackExpectation expectation) | |
373 : expectation_(expectation), did_fallback_(false) {} | |
374 | |
375 FallbackExpectation expectation_; | |
376 bool did_fallback_; | |
377 }; | |
378 | |
379 //============================================================================ | |
380 | |
381 TEST_F(CanvasRenderingContext2DTest, detectOverdrawWithFillRect) { | 346 TEST_F(CanvasRenderingContext2DTest, detectOverdrawWithFillRect) { |
382 CreateContext(kNonOpaque); | 347 CreateContext(kNonOpaque); |
383 | 348 |
384 TEST_OVERDRAW_1(1, fillRect(-1, -1, 12, 12)); | 349 TEST_OVERDRAW_1(1, fillRect(-1, -1, 12, 12)); |
385 TEST_OVERDRAW_1(1, fillRect(0, 0, 10, 10)); | 350 TEST_OVERDRAW_1(1, fillRect(0, 0, 10, 10)); |
386 TEST_OVERDRAW_1( | 351 TEST_OVERDRAW_1( |
387 0, strokeRect(0, 0, 10, | 352 0, strokeRect(0, 0, 10, |
388 10)); // stroking instead of filling does not overwrite | 353 10)); // stroking instead of filling does not overwrite |
389 TEST_OVERDRAW_2(0, setGlobalAlpha(0.5f), fillRect(0, 0, 10, 10)); | 354 TEST_OVERDRAW_2(0, setGlobalAlpha(0.5f), fillRect(0, 0, 10, 10)); |
390 TEST_OVERDRAW_1(0, fillRect(0, 0, 9, 9)); | 355 TEST_OVERDRAW_1(0, fillRect(0, 0, 9, 9)); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 fillRect(0, 0, 5, 5)); | 512 fillRect(0, 0, 5, 5)); |
548 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), | 513 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), |
549 fillRect(0, 0, 5, 5)); | 514 fillRect(0, 0, 5, 5)); |
550 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), | 515 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), |
551 fillRect(0, 0, 5, 5)); | 516 fillRect(0, 0, 5, 5)); |
552 } | 517 } |
553 | 518 |
554 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) { | 519 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) { |
555 CreateContext(kNonOpaque); | 520 CreateContext(kNonOpaque); |
556 std::unique_ptr<RecordingImageBufferSurface> surface = | 521 std::unique_ptr<RecordingImageBufferSurface> surface = |
557 WTF::WrapUnique(new RecordingImageBufferSurface( | 522 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
558 IntSize(10, 10), | 523 auto* surface_ptr = surface.get(); |
559 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
560 kNonOpaque)); | |
561 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 524 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
562 | 525 |
563 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 526 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 527 EXPECT_TRUE(surface_ptr->IsRecording()); |
564 } | 528 } |
565 | 529 |
566 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) { | 530 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) { |
567 CreateContext(kNonOpaque); | 531 CreateContext(kNonOpaque); |
568 std::unique_ptr<RecordingImageBufferSurface> surface = | 532 std::unique_ptr<RecordingImageBufferSurface> surface = |
569 WTF::WrapUnique(new RecordingImageBufferSurface( | 533 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
570 IntSize(10, 10), | 534 auto* surface_ptr = surface.get(); |
571 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
572 kNonOpaque)); | |
573 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 535 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
574 | 536 |
575 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 537 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
576 for (int i = 0; | 538 for (int i = 0; |
577 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold - 1; | 539 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold - 1; |
578 i++) { | 540 i++) { |
579 Context2d()->fillRect(0, 0, 10, 10); | 541 Context2d()->fillRect(0, 0, 10, 10); |
580 } | 542 } |
581 | 543 |
582 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 544 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 545 EXPECT_TRUE(surface_ptr->IsRecording()); |
583 } | 546 } |
584 | 547 |
585 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) { | 548 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) { |
586 CreateContext(kNonOpaque); | 549 CreateContext(kNonOpaque); |
587 std::unique_ptr<RecordingImageBufferSurface> surface = | 550 std::unique_ptr<RecordingImageBufferSurface> surface = |
588 WTF::WrapUnique(new RecordingImageBufferSurface( | 551 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
589 IntSize(10, 10), | 552 auto* surface_ptr = surface.get(); |
590 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
591 kNonOpaque)); | |
592 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 553 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
593 | 554 |
594 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 555 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
595 for (int i = 0; | 556 for (int i = 0; |
596 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold; | 557 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold; |
597 i++) { | 558 i++) { |
598 Context2d()->fillRect(0, 0, 10, 10); | 559 Context2d()->fillRect(0, 0, 10, 10); |
599 } | 560 } |
600 | 561 |
601 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 562 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 563 EXPECT_TRUE(surface_ptr->IsRecording()); |
602 } | 564 } |
603 | 565 |
604 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) { | 566 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) { |
605 CreateContext(kNonOpaque); | 567 CreateContext(kNonOpaque); |
606 std::unique_ptr<RecordingImageBufferSurface> surface = | 568 std::unique_ptr<RecordingImageBufferSurface> surface = |
607 WTF::WrapUnique(new RecordingImageBufferSurface( | 569 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
608 IntSize(10, 10), | 570 auto* surface_ptr = surface.get(); |
609 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
610 kNonOpaque)); | |
611 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 571 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
612 | 572 |
613 NonThrowableExceptionState exception_state; | 573 NonThrowableExceptionState exception_state; |
614 Element* source_canvas_element = | 574 Element* source_canvas_element = |
615 GetDocument().createElement("canvas", exception_state); | 575 GetDocument().createElement("canvas", exception_state); |
616 EXPECT_FALSE(exception_state.HadException()); | 576 EXPECT_FALSE(exception_state.HadException()); |
617 HTMLCanvasElement* source_canvas = | 577 HTMLCanvasElement* source_canvas = |
618 static_cast<HTMLCanvasElement*>(source_canvas_element); | 578 static_cast<HTMLCanvasElement*>(source_canvas_element); |
619 IntSize source_size( | 579 IntSize source_size( |
620 10, 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio); | 580 10, 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio); |
621 std::unique_ptr<UnacceleratedImageBufferSurface> source_surface = | 581 std::unique_ptr<UnacceleratedImageBufferSurface> source_surface = |
622 WTF::MakeUnique<UnacceleratedImageBufferSurface>(source_size, kNonOpaque); | 582 WTF::MakeUnique<UnacceleratedImageBufferSurface>(source_size, kNonOpaque); |
623 source_canvas->CreateImageBufferUsingSurfaceForTesting( | 583 source_canvas->CreateImageBufferUsingSurfaceForTesting( |
624 std::move(source_surface)); | 584 std::move(source_surface)); |
625 | 585 |
626 const ImageBitmapOptions default_options; | 586 const ImageBitmapOptions default_options; |
627 Optional<IntRect> crop_rect = IntRect(IntPoint(0, 0), source_size); | 587 Optional<IntRect> crop_rect = IntRect(IntPoint(0, 0), source_size); |
628 // Go through an ImageBitmap to avoid triggering a display list fallback | 588 // Go through an ImageBitmap to avoid triggering a display list fallback |
629 ImageBitmap* source_image_bitmap = | 589 ImageBitmap* source_image_bitmap = |
630 ImageBitmap::Create(source_canvas, crop_rect, default_options); | 590 ImageBitmap::Create(source_canvas, crop_rect, default_options); |
631 | 591 |
632 Context2d()->drawImage(GetScriptState(), source_image_bitmap, 0, 0, 1, 1, 0, | 592 Context2d()->drawImage(GetScriptState(), source_image_bitmap, 0, 0, 1, 1, 0, |
633 0, 1, 1, exception_state); | 593 0, 1, 1, exception_state); |
634 EXPECT_FALSE(exception_state.HadException()); | 594 EXPECT_FALSE(exception_state.HadException()); |
635 | 595 |
636 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 596 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 597 EXPECT_TRUE(surface_ptr->IsRecording()); |
637 } | 598 } |
638 | 599 |
639 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) { | 600 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) { |
640 CreateContext(kNonOpaque); | 601 CreateContext(kNonOpaque); |
641 std::unique_ptr<RecordingImageBufferSurface> surface = | 602 std::unique_ptr<RecordingImageBufferSurface> surface = |
642 WTF::WrapUnique(new RecordingImageBufferSurface( | 603 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
643 IntSize(10, 10), | 604 auto* surface_ptr = surface.get(); |
644 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
645 kNonOpaque)); | |
646 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 605 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
647 | 606 |
648 NonThrowableExceptionState exception_state; | 607 NonThrowableExceptionState exception_state; |
649 Element* source_canvas_element = | 608 Element* source_canvas_element = |
650 GetDocument().createElement("canvas", exception_state); | 609 GetDocument().createElement("canvas", exception_state); |
651 EXPECT_FALSE(exception_state.HadException()); | 610 EXPECT_FALSE(exception_state.HadException()); |
652 HTMLCanvasElement* source_canvas = | 611 HTMLCanvasElement* source_canvas = |
653 static_cast<HTMLCanvasElement*>(source_canvas_element); | 612 static_cast<HTMLCanvasElement*>(source_canvas_element); |
654 IntSize source_size( | 613 IntSize source_size( |
655 10, | 614 10, |
656 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio + 1); | 615 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio + 1); |
657 std::unique_ptr<UnacceleratedImageBufferSurface> source_surface = | 616 std::unique_ptr<UnacceleratedImageBufferSurface> source_surface = |
658 WTF::MakeUnique<UnacceleratedImageBufferSurface>(source_size, kNonOpaque); | 617 WTF::MakeUnique<UnacceleratedImageBufferSurface>(source_size, kNonOpaque); |
659 source_canvas->CreateImageBufferUsingSurfaceForTesting( | 618 source_canvas->CreateImageBufferUsingSurfaceForTesting( |
660 std::move(source_surface)); | 619 std::move(source_surface)); |
661 | 620 |
662 const ImageBitmapOptions default_options; | 621 const ImageBitmapOptions default_options; |
663 Optional<IntRect> crop_rect = IntRect(IntPoint(0, 0), source_size); | 622 Optional<IntRect> crop_rect = IntRect(IntPoint(0, 0), source_size); |
664 // Go through an ImageBitmap to avoid triggering a display list fallback | 623 // Go through an ImageBitmap to avoid triggering a display list fallback |
665 ImageBitmap* source_image_bitmap = | 624 ImageBitmap* source_image_bitmap = |
666 ImageBitmap::Create(source_canvas, crop_rect, default_options); | 625 ImageBitmap::Create(source_canvas, crop_rect, default_options); |
667 | 626 |
668 Context2d()->drawImage(GetScriptState(), source_image_bitmap, 0, 0, 1, 1, 0, | 627 Context2d()->drawImage(GetScriptState(), source_image_bitmap, 0, 0, 1, 1, 0, |
669 0, 1, 1, exception_state); | 628 0, 1, 1, exception_state); |
670 EXPECT_FALSE(exception_state.HadException()); | 629 EXPECT_FALSE(exception_state.HadException()); |
671 | 630 |
672 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 631 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 632 EXPECT_TRUE(surface_ptr->IsRecording()); |
673 } | 633 } |
674 | 634 |
675 TEST_F(CanvasRenderingContext2DTest, | 635 TEST_F(CanvasRenderingContext2DTest, |
676 NoLayerPromotionUnderExpensivePathPointCount) { | 636 NoLayerPromotionUnderExpensivePathPointCount) { |
677 CreateContext(kNonOpaque); | 637 CreateContext(kNonOpaque); |
678 std::unique_ptr<RecordingImageBufferSurface> surface = | 638 std::unique_ptr<RecordingImageBufferSurface> surface = |
679 WTF::WrapUnique(new RecordingImageBufferSurface( | 639 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
680 IntSize(10, 10), | 640 auto* surface_ptr = surface.get(); |
681 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
682 kNonOpaque)); | |
683 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 641 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
684 | 642 |
685 Context2d()->beginPath(); | 643 Context2d()->beginPath(); |
686 Context2d()->moveTo(7, 5); | 644 Context2d()->moveTo(7, 5); |
687 for (int i = 1; | 645 for (int i = 1; |
688 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1; | 646 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1; |
689 i++) { | 647 i++) { |
690 float angle_rad = | 648 float angle_rad = |
691 twoPiFloat * i / | 649 twoPiFloat * i / |
692 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1); | 650 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1); |
693 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); | 651 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); |
694 } | 652 } |
695 Context2d()->fill(); | 653 Context2d()->fill(); |
696 | 654 |
697 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 655 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 656 EXPECT_TRUE(surface_ptr->IsRecording()); |
698 } | 657 } |
699 | 658 |
700 TEST_F(CanvasRenderingContext2DTest, | 659 TEST_F(CanvasRenderingContext2DTest, |
701 LayerPromotionOverExpensivePathPointCount) { | 660 LayerPromotionOverExpensivePathPointCount) { |
702 CreateContext(kNonOpaque); | 661 CreateContext(kNonOpaque); |
703 std::unique_ptr<RecordingImageBufferSurface> surface = | 662 std::unique_ptr<RecordingImageBufferSurface> surface = |
704 WTF::WrapUnique(new RecordingImageBufferSurface( | 663 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
705 IntSize(10, 10), | 664 auto* surface_ptr = surface.get(); |
706 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
707 kNonOpaque)); | |
708 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 665 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
709 | 666 |
710 Context2d()->beginPath(); | 667 Context2d()->beginPath(); |
711 Context2d()->moveTo(7, 5); | 668 Context2d()->moveTo(7, 5); |
712 for (int i = 1; | 669 for (int i = 1; |
713 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1; | 670 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1; |
714 i++) { | 671 i++) { |
715 float angle_rad = | 672 float angle_rad = |
716 twoPiFloat * i / | 673 twoPiFloat * i / |
717 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1); | 674 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1); |
718 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); | 675 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); |
719 } | 676 } |
720 Context2d()->fill(); | 677 Context2d()->fill(); |
721 | 678 |
722 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 679 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 680 EXPECT_TRUE(surface_ptr->IsRecording()); |
723 } | 681 } |
724 | 682 |
725 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) { | 683 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) { |
726 CreateContext(kNonOpaque); | 684 CreateContext(kNonOpaque); |
727 std::unique_ptr<RecordingImageBufferSurface> surface = | 685 std::unique_ptr<RecordingImageBufferSurface> surface = |
728 WTF::WrapUnique(new RecordingImageBufferSurface( | 686 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
729 IntSize(10, 10), | 687 auto* surface_ptr = surface.get(); |
730 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
731 kNonOpaque)); | |
732 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 688 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
733 | 689 |
734 Context2d()->beginPath(); | 690 Context2d()->beginPath(); |
735 Context2d()->moveTo(1, 1); | 691 Context2d()->moveTo(1, 1); |
736 Context2d()->lineTo(5, 5); | 692 Context2d()->lineTo(5, 5); |
737 Context2d()->lineTo(9, 1); | 693 Context2d()->lineTo(9, 1); |
738 Context2d()->lineTo(5, 9); | 694 Context2d()->lineTo(5, 9); |
739 Context2d()->fill(); | 695 Context2d()->fill(); |
740 | 696 |
741 if (ExpensiveCanvasHeuristicParameters::kConcavePathsAreExpensive) { | 697 if (ExpensiveCanvasHeuristicParameters::kConcavePathsAreExpensive) { |
742 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 698 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
743 } else { | 699 } else { |
744 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 700 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
745 } | 701 } |
| 702 EXPECT_TRUE(surface_ptr->IsRecording()); |
746 } | 703 } |
747 | 704 |
748 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) { | 705 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) { |
749 CreateContext(kNonOpaque); | 706 CreateContext(kNonOpaque); |
750 std::unique_ptr<RecordingImageBufferSurface> surface = | 707 std::unique_ptr<RecordingImageBufferSurface> surface = |
751 WTF::WrapUnique(new RecordingImageBufferSurface( | 708 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
752 IntSize(10, 10), | 709 auto* surface_ptr = surface.get(); |
753 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
754 kNonOpaque)); | |
755 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 710 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
756 | 711 |
757 Context2d()->beginPath(); | 712 Context2d()->beginPath(); |
758 Context2d()->rect(1, 1, 2, 2); | 713 Context2d()->rect(1, 1, 2, 2); |
759 Context2d()->clip(); | 714 Context2d()->clip(); |
760 Context2d()->fillRect(0, 0, 4, 4); | 715 Context2d()->fillRect(0, 0, 4, 4); |
761 | 716 |
762 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 717 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 718 EXPECT_TRUE(surface_ptr->IsRecording()); |
763 } | 719 } |
764 | 720 |
765 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) { | 721 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) { |
766 CreateContext(kNonOpaque); | 722 CreateContext(kNonOpaque); |
767 std::unique_ptr<RecordingImageBufferSurface> surface = | 723 std::unique_ptr<RecordingImageBufferSurface> surface = |
768 WTF::WrapUnique(new RecordingImageBufferSurface( | 724 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
769 IntSize(10, 10), | 725 auto* surface_ptr = surface.get(); |
770 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
771 kNonOpaque)); | |
772 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 726 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
773 | 727 |
774 Context2d()->beginPath(); | 728 Context2d()->beginPath(); |
775 Context2d()->moveTo(1, 1); | 729 Context2d()->moveTo(1, 1); |
776 Context2d()->lineTo(5, 5); | 730 Context2d()->lineTo(5, 5); |
777 Context2d()->lineTo(9, 1); | 731 Context2d()->lineTo(9, 1); |
778 Context2d()->lineTo(5, 9); | 732 Context2d()->lineTo(5, 9); |
779 Context2d()->clip(); | 733 Context2d()->clip(); |
780 Context2d()->fillRect(0, 0, 4, 4); | 734 Context2d()->fillRect(0, 0, 4, 4); |
781 | 735 |
782 if (ExpensiveCanvasHeuristicParameters::kComplexClipsAreExpensive) { | 736 if (ExpensiveCanvasHeuristicParameters::kComplexClipsAreExpensive) { |
783 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 737 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
784 } else { | 738 } else { |
785 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 739 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
786 } | 740 } |
| 741 EXPECT_TRUE(surface_ptr->IsRecording()); |
787 } | 742 } |
788 | 743 |
789 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) { | 744 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) { |
790 CreateContext(kNonOpaque); | 745 CreateContext(kNonOpaque); |
791 std::unique_ptr<RecordingImageBufferSurface> surface = | 746 std::unique_ptr<RecordingImageBufferSurface> surface = |
792 WTF::WrapUnique(new RecordingImageBufferSurface( | 747 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
793 IntSize(10, 10), | 748 auto* surface_ptr = surface.get(); |
794 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
795 kNonOpaque)); | |
796 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 749 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
797 | 750 |
798 Context2d()->setShadowColor(String("red")); | 751 Context2d()->setShadowColor(String("red")); |
799 Context2d()->setShadowBlur(1.0f); | 752 Context2d()->setShadowBlur(1.0f); |
800 Context2d()->fillRect(1, 1, 1, 1); | 753 Context2d()->fillRect(1, 1, 1, 1); |
801 | 754 |
802 if (ExpensiveCanvasHeuristicParameters::kBlurredShadowsAreExpensive) { | 755 if (ExpensiveCanvasHeuristicParameters::kBlurredShadowsAreExpensive) { |
803 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 756 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
804 } else { | 757 } else { |
805 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 758 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
806 } | 759 } |
| 760 EXPECT_TRUE(surface_ptr->IsRecording()); |
807 } | 761 } |
808 | 762 |
809 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) { | 763 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) { |
810 CreateContext(kNonOpaque); | 764 CreateContext(kNonOpaque); |
811 std::unique_ptr<RecordingImageBufferSurface> surface = | 765 std::unique_ptr<RecordingImageBufferSurface> surface = |
812 WTF::WrapUnique(new RecordingImageBufferSurface( | 766 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
813 IntSize(10, 10), | 767 auto* surface_ptr = surface.get(); |
814 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
815 kNonOpaque)); | |
816 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 768 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
817 | 769 |
818 Context2d()->setShadowColor(String("red")); | 770 Context2d()->setShadowColor(String("red")); |
819 Context2d()->setShadowOffsetX(1.0f); | 771 Context2d()->setShadowOffsetX(1.0f); |
820 Context2d()->fillRect(1, 1, 1, 1); | 772 Context2d()->fillRect(1, 1, 1, 1); |
821 | 773 |
822 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 774 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 775 EXPECT_TRUE(surface_ptr->IsRecording()); |
823 } | 776 } |
824 | 777 |
825 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) { | 778 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) { |
826 CreateContext(kNonOpaque); | 779 CreateContext(kNonOpaque); |
827 std::unique_ptr<RecordingImageBufferSurface> surface = | 780 std::unique_ptr<RecordingImageBufferSurface> surface = |
828 WTF::WrapUnique(new RecordingImageBufferSurface( | 781 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
829 IntSize(10, 10), | 782 auto* surface_ptr = surface.get(); |
830 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
831 kNonOpaque)); | |
832 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 783 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
833 | 784 |
834 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 785 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect. |
835 for (int i = 0; | 786 for (int i = 0; |
836 i < | 787 i < |
837 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth - 1; | 788 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth - 1; |
838 ++i) { | 789 ++i) { |
839 Context2d()->save(); | 790 Context2d()->save(); |
840 Context2d()->translate(1.0f, 0.0f); | 791 Context2d()->translate(1.0f, 0.0f); |
841 } | 792 } |
842 CanvasElement().FinalizeFrame(); // To close the current frame | 793 CanvasElement().FinalizeFrame(); // To close the current frame. |
| 794 |
| 795 EXPECT_TRUE(surface_ptr->IsRecording()); |
843 } | 796 } |
844 | 797 |
845 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) { | 798 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) { |
846 CreateContext(kNonOpaque); | 799 CreateContext(kNonOpaque); |
847 std::unique_ptr<RecordingImageBufferSurface> surface = | 800 std::unique_ptr<RecordingImageBufferSurface> surface = |
848 WTF::WrapUnique(new RecordingImageBufferSurface( | 801 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
849 IntSize(10, 10), | 802 auto* surface_ptr = surface.get(); |
850 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), | |
851 kNonOpaque)); | |
852 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 803 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
853 | 804 |
854 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 805 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect. |
855 for (int i = 0; | 806 for (int i = 0; |
856 i < ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth; | 807 i < ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth; |
857 ++i) { | 808 ++i) { |
858 Context2d()->save(); | 809 Context2d()->save(); |
859 Context2d()->translate(1.0f, 0.0f); | 810 Context2d()->translate(1.0f, 0.0f); |
860 } | 811 } |
861 CanvasElement().FinalizeFrame(); // To close the current frame | 812 CanvasElement().FinalizeFrame(); // To close the current frame. |
| 813 |
| 814 EXPECT_FALSE(surface_ptr->IsRecording()); |
862 } | 815 } |
863 | 816 |
864 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) { | 817 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) { |
865 // Verify that drawing text to an opaque canvas, which is expected to | 818 // Verify that drawing text to an opaque canvas, which is expected to |
866 // render with subpixel text anti-aliasing, results in falling out | 819 // render with subpixel text anti-aliasing, results in falling out |
867 // of display list mode because the current diplay list implementation | 820 // of display list mode because the current diplay list implementation |
868 // does not support pixel geometry settings. | 821 // does not support pixel geometry settings. |
869 // See: crbug.com/583809 | 822 // See: crbug.com/583809 |
870 CreateContext(kOpaque); | 823 CreateContext(kOpaque); |
871 std::unique_ptr<RecordingImageBufferSurface> surface = | 824 auto surface = |
872 WTF::WrapUnique(new RecordingImageBufferSurface( | 825 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kOpaque); |
873 IntSize(10, 10), | 826 auto* surface_ptr = surface.get(); |
874 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), | |
875 kOpaque)); | |
876 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 827 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
877 | 828 |
878 Context2d()->fillText("Text", 0, 5); | 829 Context2d()->fillText("Text", 0, 5); |
| 830 |
| 831 EXPECT_FALSE(surface_ptr->IsRecording()); |
879 } | 832 } |
880 | 833 |
881 TEST_F(CanvasRenderingContext2DTest, | 834 TEST_F(CanvasRenderingContext2DTest, |
882 NonOpaqueDisplayListDoesNotFallBackForText) { | 835 NonOpaqueDisplayListDoesNotFallBackForText) { |
883 CreateContext(kNonOpaque); | 836 CreateContext(kNonOpaque); |
884 std::unique_ptr<RecordingImageBufferSurface> surface = | 837 std::unique_ptr<RecordingImageBufferSurface> surface = |
885 WTF::WrapUnique(new RecordingImageBufferSurface( | 838 WTF::MakeUnique<RecordingImageBufferSurface>(IntSize(10, 10), kNonOpaque); |
886 IntSize(10, 10), | 839 auto* surface_ptr = surface.get(); |
887 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | |
888 kNonOpaque)); | |
889 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 840 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
890 | 841 |
891 Context2d()->fillText("Text", 0, 5); | 842 Context2d()->fillText("Text", 0, 5); |
| 843 |
| 844 EXPECT_TRUE(surface_ptr->IsRecording()); |
892 } | 845 } |
893 | 846 |
894 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { | 847 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { |
895 NonThrowableExceptionState non_throwable_exception_state; | 848 NonThrowableExceptionState non_throwable_exception_state; |
896 Element* canvas_element = | 849 Element* canvas_element = |
897 GetDocument().createElement("canvas", non_throwable_exception_state); | 850 GetDocument().createElement("canvas", non_throwable_exception_state); |
898 EXPECT_FALSE(non_throwable_exception_state.HadException()); | 851 EXPECT_FALSE(non_throwable_exception_state.HadException()); |
899 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(canvas_element); | 852 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(canvas_element); |
900 canvas->SetSize(IntSize(40, 40)); | 853 canvas->SetSize(IntSize(40, 40)); |
901 ImageBitmap* image_bitmap_derived = nullptr; | 854 ImageBitmap* image_bitmap_derived = nullptr; |
(...skipping 12 matching lines...) Expand all Loading... |
914 canvas->GetCanvasRenderingContext("2d", attributes)); | 867 canvas->GetCanvasRenderingContext("2d", attributes)); |
915 DummyExceptionStateForTesting exception_state; | 868 DummyExceptionStateForTesting exception_state; |
916 CanvasImageSourceUnion image_source; | 869 CanvasImageSourceUnion image_source; |
917 image_source.setImageBitmap(image_bitmap_derived); | 870 image_source.setImageBitmap(image_bitmap_derived); |
918 context->drawImage(GetScriptState(), image_source, 0, 0, exception_state); | 871 context->drawImage(GetScriptState(), image_source, 0, 0, exception_state); |
919 } | 872 } |
920 | 873 |
921 TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { | 874 TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { |
922 CreateContext(kNonOpaque); | 875 CreateContext(kNonOpaque); |
923 | 876 |
924 std::unique_ptr<FakeAcceleratedImageBufferSurfaceForTesting> | 877 std::unique_ptr<FakeAcceleratedImageBufferSurface> fake_accelerate_surface = |
925 fake_accelerate_surface = | 878 WTF::MakeUnique<FakeAcceleratedImageBufferSurface>(IntSize(10, 10), |
926 WTF::WrapUnique(new FakeAcceleratedImageBufferSurfaceForTesting( | 879 kNonOpaque); |
927 IntSize(10, 10), kNonOpaque)); | 880 FakeAcceleratedImageBufferSurface* fake_accelerate_surface_ptr = |
928 FakeAcceleratedImageBufferSurfaceForTesting* fake_accelerate_surface_ptr = | |
929 fake_accelerate_surface.get(); | 881 fake_accelerate_surface.get(); |
930 CanvasElement().CreateImageBufferUsingSurfaceForTesting( | 882 CanvasElement().CreateImageBufferUsingSurfaceForTesting( |
931 std::move(fake_accelerate_surface)); | 883 std::move(fake_accelerate_surface)); |
932 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per | 884 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per |
933 // pixel per buffer, and 2 is an estimate of num of gpu buffers required | 885 // pixel per buffer, and 2 is an estimate of num of gpu buffers required |
934 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); | 886 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); |
935 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); | 887 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); |
936 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); | 888 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); |
937 | 889 |
938 // Switching accelerated mode to non-accelerated mode | 890 // Switching accelerated mode to non-accelerated mode |
939 fake_accelerate_surface_ptr->SetIsAccelerated(false); | 891 fake_accelerate_surface_ptr->SetIsAccelerated(false); |
940 CanvasElement().Buffer()->UpdateGPUMemoryUsage(); | 892 CanvasElement().Buffer()->UpdateGPUMemoryUsage(); |
941 EXPECT_EQ(0, GetCurrentGPUMemoryUsage()); | 893 EXPECT_EQ(0, GetCurrentGPUMemoryUsage()); |
942 EXPECT_EQ(0, GetGlobalGPUMemoryUsage()); | 894 EXPECT_EQ(0, GetGlobalGPUMemoryUsage()); |
943 EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount()); | 895 EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount()); |
944 | 896 |
945 // Switching non-accelerated mode to accelerated mode | 897 // Switching non-accelerated mode to accelerated mode |
946 fake_accelerate_surface_ptr->SetIsAccelerated(true); | 898 fake_accelerate_surface_ptr->SetIsAccelerated(true); |
947 CanvasElement().Buffer()->UpdateGPUMemoryUsage(); | 899 CanvasElement().Buffer()->UpdateGPUMemoryUsage(); |
948 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); | 900 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); |
949 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); | 901 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); |
950 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); | 902 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); |
951 | 903 |
952 // Creating a different accelerated image buffer | 904 // Creating a different accelerated image buffer |
953 std::unique_ptr<FakeAcceleratedImageBufferSurfaceForTesting> | 905 auto fake_accelerate_surface2 = |
954 fake_accelerate_surface2 = | 906 WTF::MakeUnique<FakeAcceleratedImageBufferSurface>(IntSize(10, 5), |
955 WTF::WrapUnique(new FakeAcceleratedImageBufferSurfaceForTesting( | 907 kNonOpaque); |
956 IntSize(10, 5), kNonOpaque)); | |
957 std::unique_ptr<ImageBuffer> image_buffer2 = | 908 std::unique_ptr<ImageBuffer> image_buffer2 = |
958 ImageBuffer::Create(std::move(fake_accelerate_surface2)); | 909 ImageBuffer::Create(std::move(fake_accelerate_surface2)); |
959 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); | 910 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); |
960 EXPECT_EQ(1200, GetGlobalGPUMemoryUsage()); | 911 EXPECT_EQ(1200, GetGlobalGPUMemoryUsage()); |
961 EXPECT_EQ(2u, GetGlobalAcceleratedImageBufferCount()); | 912 EXPECT_EQ(2u, GetGlobalAcceleratedImageBufferCount()); |
962 | 913 |
963 // Tear down the first image buffer that resides in current canvas element | 914 // Tear down the first image buffer that resides in current canvas element |
964 CanvasElement().SetSize(IntSize(20, 20)); | 915 CanvasElement().SetSize(IntSize(20, 20)); |
965 Mock::VerifyAndClearExpectations(fake_accelerate_surface_ptr); | 916 Mock::VerifyAndClearExpectations(fake_accelerate_surface_ptr); |
966 EXPECT_EQ(400, GetGlobalGPUMemoryUsage()); | 917 EXPECT_EQ(400, GetGlobalGPUMemoryUsage()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 } | 1061 } |
1111 // Restore global state to prevent side-effects on other tests | 1062 // Restore global state to prevent side-effects on other tests |
1112 RuntimeEnabledFeatures::setCanvas2dFixedRenderingModeEnabled( | 1063 RuntimeEnabledFeatures::setCanvas2dFixedRenderingModeEnabled( |
1113 saved_fixed_rendering_mode); | 1064 saved_fixed_rendering_mode); |
1114 } | 1065 } |
1115 | 1066 |
1116 TEST_F(CanvasRenderingContext2DTest, | 1067 TEST_F(CanvasRenderingContext2DTest, |
1117 IsAccelerationOptimalForCanvasContentHeuristic) { | 1068 IsAccelerationOptimalForCanvasContentHeuristic) { |
1118 CreateContext(kNonOpaque); | 1069 CreateContext(kNonOpaque); |
1119 | 1070 |
1120 std::unique_ptr<FakeAcceleratedImageBufferSurfaceForTesting> | 1071 auto fake_accelerate_surface = |
1121 fake_accelerate_surface = | 1072 WTF::MakeUnique<FakeAcceleratedImageBufferSurface>(IntSize(10, 10), |
1122 WTF::WrapUnique(new FakeAcceleratedImageBufferSurfaceForTesting( | 1073 kNonOpaque); |
1123 IntSize(10, 10), kNonOpaque)); | |
1124 CanvasElement().CreateImageBufferUsingSurfaceForTesting( | 1074 CanvasElement().CreateImageBufferUsingSurfaceForTesting( |
1125 std::move(fake_accelerate_surface)); | 1075 std::move(fake_accelerate_surface)); |
1126 | 1076 |
1127 NonThrowableExceptionState exception_state; | 1077 NonThrowableExceptionState exception_state; |
1128 | 1078 |
1129 CanvasRenderingContext2D* context = Context2d(); | 1079 CanvasRenderingContext2D* context = Context2d(); |
1130 EXPECT_TRUE(context->IsAccelerationOptimalForCanvasContent()); | 1080 EXPECT_TRUE(context->IsAccelerationOptimalForCanvasContent()); |
1131 | 1081 |
1132 context->fillRect(10, 10, 100, 100); | 1082 context->fillRect(10, 10, 100, 100); |
1133 EXPECT_TRUE(context->IsAccelerationOptimalForCanvasContent()); | 1083 EXPECT_TRUE(context->IsAccelerationOptimalForCanvasContent()); |
(...skipping 11 matching lines...) Expand all Loading... |
1145 | 1095 |
1146 for (int i = 0; i < num_reps * 100; i++) { | 1096 for (int i = 0; i < num_reps * 100; i++) { |
1147 context->strokeText("Text", 10, 10, 1); // faster with no acceleration | 1097 context->strokeText("Text", 10, 10, 1); // faster with no acceleration |
1148 } | 1098 } |
1149 EXPECT_FALSE(context->IsAccelerationOptimalForCanvasContent()); | 1099 EXPECT_FALSE(context->IsAccelerationOptimalForCanvasContent()); |
1150 } | 1100 } |
1151 | 1101 |
1152 TEST_F(CanvasRenderingContext2DTest, DisableAcceleration) { | 1102 TEST_F(CanvasRenderingContext2DTest, DisableAcceleration) { |
1153 CreateContext(kNonOpaque); | 1103 CreateContext(kNonOpaque); |
1154 | 1104 |
1155 std::unique_ptr<FakeAcceleratedImageBufferSurfaceForTesting> | 1105 auto fake_accelerate_surface = |
1156 fake_accelerate_surface = | 1106 WTF::MakeUnique<FakeAcceleratedImageBufferSurface>(IntSize(10, 10), |
1157 WTF::WrapUnique(new FakeAcceleratedImageBufferSurfaceForTesting( | 1107 kNonOpaque); |
1158 IntSize(10, 10), kNonOpaque)); | |
1159 CanvasElement().CreateImageBufferUsingSurfaceForTesting( | 1108 CanvasElement().CreateImageBufferUsingSurfaceForTesting( |
1160 std::move(fake_accelerate_surface)); | 1109 std::move(fake_accelerate_surface)); |
1161 CanvasRenderingContext2D* context = Context2d(); | 1110 CanvasRenderingContext2D* context = Context2d(); |
1162 | 1111 |
1163 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per | 1112 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per |
1164 // pixel per buffer, and 2 is an estimate of num of gpu buffers required | 1113 // pixel per buffer, and 2 is an estimate of num of gpu buffers required |
1165 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); | 1114 EXPECT_EQ(800, GetCurrentGPUMemoryUsage()); |
1166 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); | 1115 EXPECT_EQ(800, GetGlobalGPUMemoryUsage()); |
1167 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); | 1116 EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount()); |
1168 | 1117 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 EXPECT_FALSE(layer->NeedsCompositingInputsUpdate()); | 1402 EXPECT_FALSE(layer->NeedsCompositingInputsUpdate()); |
1454 | 1403 |
1455 // Wake up again, which should request a compositing update synchronously. | 1404 // Wake up again, which should request a compositing update synchronously. |
1456 GetDocument().GetPage()->SetVisibilityState(kPageVisibilityStateVisible, | 1405 GetDocument().GetPage()->SetVisibilityState(kPageVisibilityStateVisible, |
1457 false); | 1406 false); |
1458 EXPECT_EQ(!!CANVAS2D_HIBERNATION_ENABLED, | 1407 EXPECT_EQ(!!CANVAS2D_HIBERNATION_ENABLED, |
1459 layer->NeedsCompositingInputsUpdate()); | 1408 layer->NeedsCompositingInputsUpdate()); |
1460 } | 1409 } |
1461 | 1410 |
1462 } // namespace blink | 1411 } // namespace blink |
OLD | NEW |