| 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 |