| 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, | 236 ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, |
| 237 BlinkGC::kGCWithSweep, | 237 BlinkGC::kGCWithSweep, |
| 238 BlinkGC::kForcedGC); | 238 BlinkGC::kForcedGC); |
| 239 ReplaceMemoryCacheForTesting(global_memory_cache_.Release()); | 239 ReplaceMemoryCacheForTesting(global_memory_cache_.Release()); |
| 240 } | 240 } |
| 241 | 241 |
| 242 PassRefPtr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge( | 242 PassRefPtr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge( |
| 243 std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, | 243 std::unique_ptr<FakeWebGraphicsContext3DProvider> provider, |
| 244 const IntSize& size, | 244 const IntSize& size, |
| 245 Canvas2DLayerBridge::AccelerationMode acceleration_mode) { | 245 Canvas2DLayerBridge::AccelerationMode acceleration_mode) { |
| 246 return AdoptRef(new Canvas2DLayerBridge( | 246 return AdoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, |
| 247 std::move(provider), size, 0, kNonOpaque, acceleration_mode, | 247 kNonOpaque, acceleration_mode, |
| 248 gfx::ColorSpace::CreateSRGB(), false, kN32_SkColorType)); | 248 CanvasColorParams())); |
| 249 } | 249 } |
| 250 | 250 |
| 251 //============================================================================ | 251 //============================================================================ |
| 252 | 252 |
| 253 class FakeAcceleratedImageBufferSurfaceForTesting | 253 class FakeAcceleratedImageBufferSurfaceForTesting |
| 254 : public UnacceleratedImageBufferSurface { | 254 : public UnacceleratedImageBufferSurface { |
| 255 public: | 255 public: |
| 256 FakeAcceleratedImageBufferSurfaceForTesting(const IntSize& size, | 256 FakeAcceleratedImageBufferSurfaceForTesting(const IntSize& size, |
| 257 OpacityMode mode) | 257 OpacityMode mode) |
| 258 : UnacceleratedImageBufferSurface(size, mode), is_accelerated_(true) {} | 258 : UnacceleratedImageBufferSurface(size, mode), is_accelerated_(true) {} |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 public: | 339 public: |
| 340 enum FallbackExpectation { kExpectFallback, kExpectNoFallback }; | 340 enum FallbackExpectation { kExpectFallback, kExpectNoFallback }; |
| 341 static std::unique_ptr<MockSurfaceFactory> Create( | 341 static std::unique_ptr<MockSurfaceFactory> Create( |
| 342 FallbackExpectation expectation) { | 342 FallbackExpectation expectation) { |
| 343 return WTF::WrapUnique(new MockSurfaceFactory(expectation)); | 343 return WTF::WrapUnique(new MockSurfaceFactory(expectation)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 std::unique_ptr<ImageBufferSurface> CreateSurface( | 346 std::unique_ptr<ImageBufferSurface> CreateSurface( |
| 347 const IntSize& size, | 347 const IntSize& size, |
| 348 OpacityMode mode, | 348 OpacityMode mode, |
| 349 sk_sp<SkColorSpace> color_space, | 349 const CanvasColorParams& color_params) override { |
| 350 SkColorType color_type) override { | |
| 351 EXPECT_EQ(kExpectFallback, expectation_); | 350 EXPECT_EQ(kExpectFallback, expectation_); |
| 352 did_fallback_ = true; | 351 did_fallback_ = true; |
| 353 return WTF::WrapUnique(new UnacceleratedImageBufferSurface( | 352 return WTF::WrapUnique(new UnacceleratedImageBufferSurface( |
| 354 size, mode, kInitializeImagePixels, color_space, color_type)); | 353 size, mode, kInitializeImagePixels, color_params)); |
| 355 } | 354 } |
| 356 | 355 |
| 357 ~MockSurfaceFactory() override { | 356 ~MockSurfaceFactory() override { |
| 358 if (expectation_ == kExpectFallback) { | 357 if (expectation_ == kExpectFallback) { |
| 359 EXPECT_TRUE(did_fallback_); | 358 EXPECT_TRUE(did_fallback_); |
| 360 } | 359 } |
| 361 } | 360 } |
| 362 | 361 |
| 363 private: | 362 private: |
| 364 MockSurfaceFactory(FallbackExpectation expectation) | 363 MockSurfaceFactory(FallbackExpectation expectation) |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), | 541 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), |
| 543 fillRect(0, 0, 5, 5)); | 542 fillRect(0, 0, 5, 5)); |
| 544 } | 543 } |
| 545 | 544 |
| 546 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) { | 545 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) { |
| 547 CreateContext(kNonOpaque); | 546 CreateContext(kNonOpaque); |
| 548 std::unique_ptr<RecordingImageBufferSurface> surface = | 547 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 549 WTF::WrapUnique(new RecordingImageBufferSurface( | 548 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 550 IntSize(10, 10), | 549 IntSize(10, 10), |
| 551 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 550 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 552 kNonOpaque, nullptr)); | 551 kNonOpaque)); |
| 553 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 552 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 554 | 553 |
| 555 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 554 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 556 } | 555 } |
| 557 | 556 |
| 558 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) { | 557 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) { |
| 559 CreateContext(kNonOpaque); | 558 CreateContext(kNonOpaque); |
| 560 std::unique_ptr<RecordingImageBufferSurface> surface = | 559 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 561 WTF::WrapUnique(new RecordingImageBufferSurface( | 560 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 562 IntSize(10, 10), | 561 IntSize(10, 10), |
| 563 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 562 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 564 kNonOpaque, nullptr)); | 563 kNonOpaque)); |
| 565 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 564 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 566 | 565 |
| 567 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 566 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 568 for (int i = 0; | 567 for (int i = 0; |
| 569 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold - 1; | 568 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold - 1; |
| 570 i++) { | 569 i++) { |
| 571 Context2d()->fillRect(0, 0, 10, 10); | 570 Context2d()->fillRect(0, 0, 10, 10); |
| 572 } | 571 } |
| 573 | 572 |
| 574 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 573 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 575 } | 574 } |
| 576 | 575 |
| 577 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) { | 576 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) { |
| 578 CreateContext(kNonOpaque); | 577 CreateContext(kNonOpaque); |
| 579 std::unique_ptr<RecordingImageBufferSurface> surface = | 578 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 580 WTF::WrapUnique(new RecordingImageBufferSurface( | 579 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 581 IntSize(10, 10), | 580 IntSize(10, 10), |
| 582 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 581 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 583 kNonOpaque, nullptr)); | 582 kNonOpaque)); |
| 584 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 583 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 585 | 584 |
| 586 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 585 Context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 587 for (int i = 0; | 586 for (int i = 0; |
| 588 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold; | 587 i < ExpensiveCanvasHeuristicParameters::kExpensiveOverdrawThreshold; |
| 589 i++) { | 588 i++) { |
| 590 Context2d()->fillRect(0, 0, 10, 10); | 589 Context2d()->fillRect(0, 0, 10, 10); |
| 591 } | 590 } |
| 592 | 591 |
| 593 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 592 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 594 } | 593 } |
| 595 | 594 |
| 596 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) { | 595 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) { |
| 597 CreateContext(kNonOpaque); | 596 CreateContext(kNonOpaque); |
| 598 std::unique_ptr<RecordingImageBufferSurface> surface = | 597 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 599 WTF::WrapUnique(new RecordingImageBufferSurface( | 598 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 600 IntSize(10, 10), | 599 IntSize(10, 10), |
| 601 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 600 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 602 kNonOpaque, nullptr)); | 601 kNonOpaque)); |
| 603 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 602 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 604 | 603 |
| 605 NonThrowableExceptionState exception_state; | 604 NonThrowableExceptionState exception_state; |
| 606 Element* source_canvas_element = | 605 Element* source_canvas_element = |
| 607 GetDocument().createElement("canvas", exception_state); | 606 GetDocument().createElement("canvas", exception_state); |
| 608 EXPECT_FALSE(exception_state.HadException()); | 607 EXPECT_FALSE(exception_state.HadException()); |
| 609 HTMLCanvasElement* source_canvas = | 608 HTMLCanvasElement* source_canvas = |
| 610 static_cast<HTMLCanvasElement*>(source_canvas_element); | 609 static_cast<HTMLCanvasElement*>(source_canvas_element); |
| 611 IntSize source_size( | 610 IntSize source_size( |
| 612 10, 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio); | 611 10, 10 * ExpensiveCanvasHeuristicParameters::kExpensiveImageSizeRatio); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 627 | 626 |
| 628 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 627 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 629 } | 628 } |
| 630 | 629 |
| 631 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) { | 630 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) { |
| 632 CreateContext(kNonOpaque); | 631 CreateContext(kNonOpaque); |
| 633 std::unique_ptr<RecordingImageBufferSurface> surface = | 632 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 634 WTF::WrapUnique(new RecordingImageBufferSurface( | 633 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 635 IntSize(10, 10), | 634 IntSize(10, 10), |
| 636 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 635 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 637 kNonOpaque, nullptr)); | 636 kNonOpaque)); |
| 638 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 637 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 639 | 638 |
| 640 NonThrowableExceptionState exception_state; | 639 NonThrowableExceptionState exception_state; |
| 641 Element* source_canvas_element = | 640 Element* source_canvas_element = |
| 642 GetDocument().createElement("canvas", exception_state); | 641 GetDocument().createElement("canvas", exception_state); |
| 643 EXPECT_FALSE(exception_state.HadException()); | 642 EXPECT_FALSE(exception_state.HadException()); |
| 644 HTMLCanvasElement* source_canvas = | 643 HTMLCanvasElement* source_canvas = |
| 645 static_cast<HTMLCanvasElement*>(source_canvas_element); | 644 static_cast<HTMLCanvasElement*>(source_canvas_element); |
| 646 IntSize source_size( | 645 IntSize source_size( |
| 647 10, | 646 10, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 664 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 663 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 665 } | 664 } |
| 666 | 665 |
| 667 TEST_F(CanvasRenderingContext2DTest, | 666 TEST_F(CanvasRenderingContext2DTest, |
| 668 NoLayerPromotionUnderExpensivePathPointCount) { | 667 NoLayerPromotionUnderExpensivePathPointCount) { |
| 669 CreateContext(kNonOpaque); | 668 CreateContext(kNonOpaque); |
| 670 std::unique_ptr<RecordingImageBufferSurface> surface = | 669 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 671 WTF::WrapUnique(new RecordingImageBufferSurface( | 670 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 672 IntSize(10, 10), | 671 IntSize(10, 10), |
| 673 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 672 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 674 kNonOpaque, nullptr)); | 673 kNonOpaque)); |
| 675 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 674 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 676 | 675 |
| 677 Context2d()->beginPath(); | 676 Context2d()->beginPath(); |
| 678 Context2d()->moveTo(7, 5); | 677 Context2d()->moveTo(7, 5); |
| 679 for (int i = 1; | 678 for (int i = 1; |
| 680 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1; | 679 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1; |
| 681 i++) { | 680 i++) { |
| 682 float angle_rad = | 681 float angle_rad = |
| 683 twoPiFloat * i / | 682 twoPiFloat * i / |
| 684 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1); | 683 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount - 1); |
| 685 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); | 684 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); |
| 686 } | 685 } |
| 687 Context2d()->fill(); | 686 Context2d()->fill(); |
| 688 | 687 |
| 689 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 688 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 690 } | 689 } |
| 691 | 690 |
| 692 TEST_F(CanvasRenderingContext2DTest, | 691 TEST_F(CanvasRenderingContext2DTest, |
| 693 LayerPromotionOverExpensivePathPointCount) { | 692 LayerPromotionOverExpensivePathPointCount) { |
| 694 CreateContext(kNonOpaque); | 693 CreateContext(kNonOpaque); |
| 695 std::unique_ptr<RecordingImageBufferSurface> surface = | 694 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 696 WTF::WrapUnique(new RecordingImageBufferSurface( | 695 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 697 IntSize(10, 10), | 696 IntSize(10, 10), |
| 698 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 697 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 699 kNonOpaque, nullptr)); | 698 kNonOpaque)); |
| 700 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 699 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 701 | 700 |
| 702 Context2d()->beginPath(); | 701 Context2d()->beginPath(); |
| 703 Context2d()->moveTo(7, 5); | 702 Context2d()->moveTo(7, 5); |
| 704 for (int i = 1; | 703 for (int i = 1; |
| 705 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1; | 704 i < ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1; |
| 706 i++) { | 705 i++) { |
| 707 float angle_rad = | 706 float angle_rad = |
| 708 twoPiFloat * i / | 707 twoPiFloat * i / |
| 709 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1); | 708 (ExpensiveCanvasHeuristicParameters::kExpensivePathPointCount + 1); |
| 710 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); | 709 Context2d()->lineTo(5 + 2 * cos(angle_rad), 5 + 2 * sin(angle_rad)); |
| 711 } | 710 } |
| 712 Context2d()->fill(); | 711 Context2d()->fill(); |
| 713 | 712 |
| 714 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 713 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 715 } | 714 } |
| 716 | 715 |
| 717 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) { | 716 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) { |
| 718 CreateContext(kNonOpaque); | 717 CreateContext(kNonOpaque); |
| 719 std::unique_ptr<RecordingImageBufferSurface> surface = | 718 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 720 WTF::WrapUnique(new RecordingImageBufferSurface( | 719 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 721 IntSize(10, 10), | 720 IntSize(10, 10), |
| 722 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 721 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 723 kNonOpaque, nullptr)); | 722 kNonOpaque)); |
| 724 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 723 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 725 | 724 |
| 726 Context2d()->beginPath(); | 725 Context2d()->beginPath(); |
| 727 Context2d()->moveTo(1, 1); | 726 Context2d()->moveTo(1, 1); |
| 728 Context2d()->lineTo(5, 5); | 727 Context2d()->lineTo(5, 5); |
| 729 Context2d()->lineTo(9, 1); | 728 Context2d()->lineTo(9, 1); |
| 730 Context2d()->lineTo(5, 9); | 729 Context2d()->lineTo(5, 9); |
| 731 Context2d()->fill(); | 730 Context2d()->fill(); |
| 732 | 731 |
| 733 if (ExpensiveCanvasHeuristicParameters::kConcavePathsAreExpensive) { | 732 if (ExpensiveCanvasHeuristicParameters::kConcavePathsAreExpensive) { |
| 734 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 733 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 735 } else { | 734 } else { |
| 736 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 735 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 737 } | 736 } |
| 738 } | 737 } |
| 739 | 738 |
| 740 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) { | 739 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) { |
| 741 CreateContext(kNonOpaque); | 740 CreateContext(kNonOpaque); |
| 742 std::unique_ptr<RecordingImageBufferSurface> surface = | 741 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 743 WTF::WrapUnique(new RecordingImageBufferSurface( | 742 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 744 IntSize(10, 10), | 743 IntSize(10, 10), |
| 745 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 744 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 746 kNonOpaque, nullptr)); | 745 kNonOpaque)); |
| 747 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 746 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 748 | 747 |
| 749 Context2d()->beginPath(); | 748 Context2d()->beginPath(); |
| 750 Context2d()->rect(1, 1, 2, 2); | 749 Context2d()->rect(1, 1, 2, 2); |
| 751 Context2d()->clip(); | 750 Context2d()->clip(); |
| 752 Context2d()->fillRect(0, 0, 4, 4); | 751 Context2d()->fillRect(0, 0, 4, 4); |
| 753 | 752 |
| 754 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 753 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 755 } | 754 } |
| 756 | 755 |
| 757 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) { | 756 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) { |
| 758 CreateContext(kNonOpaque); | 757 CreateContext(kNonOpaque); |
| 759 std::unique_ptr<RecordingImageBufferSurface> surface = | 758 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 760 WTF::WrapUnique(new RecordingImageBufferSurface( | 759 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 761 IntSize(10, 10), | 760 IntSize(10, 10), |
| 762 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 761 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 763 kNonOpaque, nullptr)); | 762 kNonOpaque)); |
| 764 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 763 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 765 | 764 |
| 766 Context2d()->beginPath(); | 765 Context2d()->beginPath(); |
| 767 Context2d()->moveTo(1, 1); | 766 Context2d()->moveTo(1, 1); |
| 768 Context2d()->lineTo(5, 5); | 767 Context2d()->lineTo(5, 5); |
| 769 Context2d()->lineTo(9, 1); | 768 Context2d()->lineTo(9, 1); |
| 770 Context2d()->lineTo(5, 9); | 769 Context2d()->lineTo(5, 9); |
| 771 Context2d()->clip(); | 770 Context2d()->clip(); |
| 772 Context2d()->fillRect(0, 0, 4, 4); | 771 Context2d()->fillRect(0, 0, 4, 4); |
| 773 | 772 |
| 774 if (ExpensiveCanvasHeuristicParameters::kComplexClipsAreExpensive) { | 773 if (ExpensiveCanvasHeuristicParameters::kComplexClipsAreExpensive) { |
| 775 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 774 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 776 } else { | 775 } else { |
| 777 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 776 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 778 } | 777 } |
| 779 } | 778 } |
| 780 | 779 |
| 781 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) { | 780 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) { |
| 782 CreateContext(kNonOpaque); | 781 CreateContext(kNonOpaque); |
| 783 std::unique_ptr<RecordingImageBufferSurface> surface = | 782 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 784 WTF::WrapUnique(new RecordingImageBufferSurface( | 783 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 785 IntSize(10, 10), | 784 IntSize(10, 10), |
| 786 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 785 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 787 kNonOpaque, nullptr)); | 786 kNonOpaque)); |
| 788 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 787 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 789 | 788 |
| 790 Context2d()->setShadowColor(String("red")); | 789 Context2d()->setShadowColor(String("red")); |
| 791 Context2d()->setShadowBlur(1.0f); | 790 Context2d()->setShadowBlur(1.0f); |
| 792 Context2d()->fillRect(1, 1, 1, 1); | 791 Context2d()->fillRect(1, 1, 1, 1); |
| 793 | 792 |
| 794 if (ExpensiveCanvasHeuristicParameters::kBlurredShadowsAreExpensive) { | 793 if (ExpensiveCanvasHeuristicParameters::kBlurredShadowsAreExpensive) { |
| 795 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); | 794 EXPECT_TRUE(CanvasElement().ShouldBeDirectComposited()); |
| 796 } else { | 795 } else { |
| 797 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 796 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 798 } | 797 } |
| 799 } | 798 } |
| 800 | 799 |
| 801 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) { | 800 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) { |
| 802 CreateContext(kNonOpaque); | 801 CreateContext(kNonOpaque); |
| 803 std::unique_ptr<RecordingImageBufferSurface> surface = | 802 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 804 WTF::WrapUnique(new RecordingImageBufferSurface( | 803 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 805 IntSize(10, 10), | 804 IntSize(10, 10), |
| 806 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 805 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 807 kNonOpaque, nullptr)); | 806 kNonOpaque)); |
| 808 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 807 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 809 | 808 |
| 810 Context2d()->setShadowColor(String("red")); | 809 Context2d()->setShadowColor(String("red")); |
| 811 Context2d()->setShadowOffsetX(1.0f); | 810 Context2d()->setShadowOffsetX(1.0f); |
| 812 Context2d()->fillRect(1, 1, 1, 1); | 811 Context2d()->fillRect(1, 1, 1, 1); |
| 813 | 812 |
| 814 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); | 813 EXPECT_FALSE(CanvasElement().ShouldBeDirectComposited()); |
| 815 } | 814 } |
| 816 | 815 |
| 817 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) { | 816 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) { |
| 818 CreateContext(kNonOpaque); | 817 CreateContext(kNonOpaque); |
| 819 std::unique_ptr<RecordingImageBufferSurface> surface = | 818 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 820 WTF::WrapUnique(new RecordingImageBufferSurface( | 819 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 821 IntSize(10, 10), | 820 IntSize(10, 10), |
| 822 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 821 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 823 kNonOpaque, nullptr)); | 822 kNonOpaque)); |
| 824 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 823 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 825 | 824 |
| 826 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 825 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 827 for (int i = 0; | 826 for (int i = 0; |
| 828 i < | 827 i < |
| 829 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth - 1; | 828 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth - 1; |
| 830 ++i) { | 829 ++i) { |
| 831 Context2d()->save(); | 830 Context2d()->save(); |
| 832 Context2d()->translate(1.0f, 0.0f); | 831 Context2d()->translate(1.0f, 0.0f); |
| 833 } | 832 } |
| 834 CanvasElement().FinalizeFrame(); // To close the current frame | 833 CanvasElement().FinalizeFrame(); // To close the current frame |
| 835 } | 834 } |
| 836 | 835 |
| 837 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) { | 836 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) { |
| 838 CreateContext(kNonOpaque); | 837 CreateContext(kNonOpaque); |
| 839 std::unique_ptr<RecordingImageBufferSurface> surface = | 838 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 840 WTF::WrapUnique(new RecordingImageBufferSurface( | 839 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 841 IntSize(10, 10), | 840 IntSize(10, 10), |
| 842 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), | 841 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), |
| 843 kNonOpaque, nullptr)); | 842 kNonOpaque)); |
| 844 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 843 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 845 | 844 |
| 846 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 845 Context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 847 for (int i = 0; | 846 for (int i = 0; |
| 848 i < ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth; | 847 i < ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth; |
| 849 ++i) { | 848 ++i) { |
| 850 Context2d()->save(); | 849 Context2d()->save(); |
| 851 Context2d()->translate(1.0f, 0.0f); | 850 Context2d()->translate(1.0f, 0.0f); |
| 852 } | 851 } |
| 853 CanvasElement().FinalizeFrame(); // To close the current frame | 852 CanvasElement().FinalizeFrame(); // To close the current frame |
| 854 } | 853 } |
| 855 | 854 |
| 856 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) { | 855 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) { |
| 857 // Verify that drawing text to an opaque canvas, which is expected to | 856 // Verify that drawing text to an opaque canvas, which is expected to |
| 858 // render with subpixel text anti-aliasing, results in falling out | 857 // render with subpixel text anti-aliasing, results in falling out |
| 859 // of display list mode because the current diplay list implementation | 858 // of display list mode because the current diplay list implementation |
| 860 // does not support pixel geometry settings. | 859 // does not support pixel geometry settings. |
| 861 // See: crbug.com/583809 | 860 // See: crbug.com/583809 |
| 862 CreateContext(kOpaque); | 861 CreateContext(kOpaque); |
| 863 std::unique_ptr<RecordingImageBufferSurface> surface = | 862 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 864 WTF::WrapUnique(new RecordingImageBufferSurface( | 863 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 865 IntSize(10, 10), | 864 IntSize(10, 10), |
| 866 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), | 865 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectFallback), |
| 867 kOpaque, nullptr)); | 866 kOpaque)); |
| 868 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 867 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 869 | 868 |
| 870 Context2d()->fillText("Text", 0, 5); | 869 Context2d()->fillText("Text", 0, 5); |
| 871 } | 870 } |
| 872 | 871 |
| 873 TEST_F(CanvasRenderingContext2DTest, | 872 TEST_F(CanvasRenderingContext2DTest, |
| 874 NonOpaqueDisplayListDoesNotFallBackForText) { | 873 NonOpaqueDisplayListDoesNotFallBackForText) { |
| 875 CreateContext(kNonOpaque); | 874 CreateContext(kNonOpaque); |
| 876 std::unique_ptr<RecordingImageBufferSurface> surface = | 875 std::unique_ptr<RecordingImageBufferSurface> surface = |
| 877 WTF::WrapUnique(new RecordingImageBufferSurface( | 876 WTF::WrapUnique(new RecordingImageBufferSurface( |
| 878 IntSize(10, 10), | 877 IntSize(10, 10), |
| 879 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), | 878 MockSurfaceFactory::Create(MockSurfaceFactory::kExpectNoFallback), |
| 880 kNonOpaque, nullptr)); | 879 kNonOpaque)); |
| 881 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); | 880 CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 882 | 881 |
| 883 Context2d()->fillText("Text", 0, 5); | 882 Context2d()->fillText("Text", 0, 5); |
| 884 } | 883 } |
| 885 | 884 |
| 886 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { | 885 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { |
| 887 NonThrowableExceptionState non_throwable_exception_state; | 886 NonThrowableExceptionState non_throwable_exception_state; |
| 888 Element* canvas_element = | 887 Element* canvas_element = |
| 889 GetDocument().createElement("canvas", non_throwable_exception_state); | 888 GetDocument().createElement("canvas", non_throwable_exception_state); |
| 890 EXPECT_FALSE(non_throwable_exception_state.HadException()); | 889 EXPECT_FALSE(non_throwable_exception_state.HadException()); |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 | 1378 |
| 1380 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( | 1379 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( |
| 1381 experimental_canvas_features_runtime_flag); | 1380 experimental_canvas_features_runtime_flag); |
| 1382 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( | 1381 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( |
| 1383 color_correct_rendering_runtime_flag); | 1382 color_correct_rendering_runtime_flag); |
| 1384 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled( | 1383 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled( |
| 1385 color_correct_rendering_default_mode_runtime_flag); | 1384 color_correct_rendering_default_mode_runtime_flag); |
| 1386 } | 1385 } |
| 1387 | 1386 |
| 1388 } // namespace blink | 1387 } // namespace blink |
| OLD | NEW |