| 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 "core/fetch/MemoryCache.h" | 7 #include "core/fetch/MemoryCache.h" |
| 8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
| 9 #include "core/frame/ImageBitmap.h" | 9 #include "core/frame/ImageBitmap.h" |
| 10 #include "core/html/HTMLCanvasElement.h" | 10 #include "core/html/HTMLCanvasElement.h" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 bool isRecording() const override { return true; } // otherwise overwrites a
re not tracked | 202 bool isRecording() const override { return true; } // otherwise overwrites a
re not tracked |
| 203 | 203 |
| 204 MOCK_METHOD0(willOverwriteCanvas, void()); | 204 MOCK_METHOD0(willOverwriteCanvas, void()); |
| 205 }; | 205 }; |
| 206 | 206 |
| 207 //============================================================================ | 207 //============================================================================ |
| 208 | 208 |
| 209 #define TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ | 209 #define TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ |
| 210 OwnPtr<MockImageBufferSurfaceForOverwriteTesting> mockSurface = adoptPtr
(new MockImageBufferSurfaceForOverwriteTesting(IntSize(10, 10), NonOpaque)); \ | 210 OwnPtr<MockImageBufferSurfaceForOverwriteTesting> mockSurface = adoptPtr
(new MockImageBufferSurfaceForOverwriteTesting(IntSize(10, 10), NonOpaque)); \ |
| 211 MockImageBufferSurfaceForOverwriteTesting* surfacePtr = mockSurface.get(
); \ | 211 MockImageBufferSurfaceForOverwriteTesting* surfacePtr = mockSurface.get(
); \ |
| 212 canvasElement().createImageBufferUsingSurfaceForTesting(mockSurface.rele
ase()); \ | 212 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(mockSu
rface)); \ |
| 213 EXPECT_CALL(*surfacePtr, willOverwriteCanvas()).Times(EXPECTED_OVERDRAWS
); \ | 213 EXPECT_CALL(*surfacePtr, willOverwriteCanvas()).Times(EXPECTED_OVERDRAWS
); \ |
| 214 context2d()->save(); | 214 context2d()->save(); |
| 215 | 215 |
| 216 #define TEST_OVERDRAW_FINALIZE \ | 216 #define TEST_OVERDRAW_FINALIZE \ |
| 217 context2d()->restore(); \ | 217 context2d()->restore(); \ |
| 218 Mock::VerifyAndClearExpectations(surfacePtr); | 218 Mock::VerifyAndClearExpectations(surfacePtr); |
| 219 | 219 |
| 220 #define TEST_OVERDRAW_1(EXPECTED_OVERDRAWS, CALL1) \ | 220 #define TEST_OVERDRAW_1(EXPECTED_OVERDRAWS, CALL1) \ |
| 221 do { \ | 221 do { \ |
| 222 TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ | 222 TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("clear")), fillRect(0,
0, 5, 5)); | 399 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("clear")), fillRect(0,
0, 5, 5)); |
| 400 TEST_OVERDRAW_2(1, setGlobalCompositeOperation(String("copy")), fillRect(0,
0, 5, 5)); | 400 TEST_OVERDRAW_2(1, setGlobalCompositeOperation(String("copy")), fillRect(0,
0, 5, 5)); |
| 401 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), fillR
ect(0, 0, 5, 5)); | 401 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), fillR
ect(0, 0, 5, 5)); |
| 402 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), fillRec
t(0, 0, 5, 5)); | 402 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), fillRec
t(0, 0, 5, 5)); |
| 403 } | 403 } |
| 404 | 404 |
| 405 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) | 405 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) |
| 406 { | 406 { |
| 407 createContext(NonOpaque); | 407 createContext(NonOpaque); |
| 408 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 408 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 409 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 409 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 410 | 410 |
| 411 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 411 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 412 } | 412 } |
| 413 | 413 |
| 414 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) | 414 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) |
| 415 { | 415 { |
| 416 createContext(NonOpaque); | 416 createContext(NonOpaque); |
| 417 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 417 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 418 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 418 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 419 | 419 |
| 420 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 420 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 421 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold - 1; i++) { | 421 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold - 1; i++) { |
| 422 context2d()->fillRect(0, 0, 10, 10); | 422 context2d()->fillRect(0, 0, 10, 10); |
| 423 } | 423 } |
| 424 | 424 |
| 425 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 425 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 426 } | 426 } |
| 427 | 427 |
| 428 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) | 428 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) |
| 429 { | 429 { |
| 430 createContext(NonOpaque); | 430 createContext(NonOpaque); |
| 431 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 431 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 432 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 432 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 433 | 433 |
| 434 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 434 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 435 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold; i++) { | 435 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold; i++) { |
| 436 context2d()->fillRect(0, 0, 10, 10); | 436 context2d()->fillRect(0, 0, 10, 10); |
| 437 } | 437 } |
| 438 | 438 |
| 439 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 439 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 440 } | 440 } |
| 441 | 441 |
| 442 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) | 442 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) |
| 443 { | 443 { |
| 444 createContext(NonOpaque); | 444 createContext(NonOpaque); |
| 445 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 445 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 446 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 446 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 447 | 447 |
| 448 NonThrowableExceptionState exceptionState; | 448 NonThrowableExceptionState exceptionState; |
| 449 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); | 449 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); |
| 450 EXPECT_FALSE(exceptionState.hadException()); | 450 EXPECT_FALSE(exceptionState.hadException()); |
| 451 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); | 451 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); |
| 452 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio); | 452 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio); |
| 453 OwnPtr<UnacceleratedImageBufferSurface> sourceSurface = adoptPtr(new Unaccel
eratedImageBufferSurface(sourceSize, NonOpaque)); | 453 OwnPtr<UnacceleratedImageBufferSurface> sourceSurface = adoptPtr(new Unaccel
eratedImageBufferSurface(sourceSize, NonOpaque)); |
| 454 sourceCanvas->createImageBufferUsingSurfaceForTesting(sourceSurface.release(
)); | 454 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); |
| 455 | 455 |
| 456 const ImageBitmapOptions defaultOptions; | 456 const ImageBitmapOptions defaultOptions; |
| 457 // Go through an ImageBitmap to avoid triggering a display list fallback | 457 // Go through an ImageBitmap to avoid triggering a display list fallback |
| 458 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, IntRect(I
ntPoint(0, 0), sourceSize), defaultOptions); | 458 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, IntRect(I
ntPoint(0, 0), sourceSize), defaultOptions); |
| 459 | 459 |
| 460 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); | 460 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); |
| 461 EXPECT_FALSE(exceptionState.hadException()); | 461 EXPECT_FALSE(exceptionState.hadException()); |
| 462 | 462 |
| 463 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 463 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 464 } | 464 } |
| 465 | 465 |
| 466 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) | 466 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) |
| 467 { | 467 { |
| 468 createContext(NonOpaque); | 468 createContext(NonOpaque); |
| 469 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 469 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 470 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 470 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 471 | 471 |
| 472 NonThrowableExceptionState exceptionState; | 472 NonThrowableExceptionState exceptionState; |
| 473 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); | 473 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); |
| 474 EXPECT_FALSE(exceptionState.hadException()); | 474 EXPECT_FALSE(exceptionState.hadException()); |
| 475 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); | 475 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); |
| 476 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio + 1); | 476 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio + 1); |
| 477 OwnPtr<UnacceleratedImageBufferSurface> sourceSurface = adoptPtr(new Unaccel
eratedImageBufferSurface(sourceSize, NonOpaque)); | 477 OwnPtr<UnacceleratedImageBufferSurface> sourceSurface = adoptPtr(new Unaccel
eratedImageBufferSurface(sourceSize, NonOpaque)); |
| 478 sourceCanvas->createImageBufferUsingSurfaceForTesting(sourceSurface.release(
)); | 478 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); |
| 479 | 479 |
| 480 const ImageBitmapOptions defaultOptions; | 480 const ImageBitmapOptions defaultOptions; |
| 481 // Go through an ImageBitmap to avoid triggering a display list fallback | 481 // Go through an ImageBitmap to avoid triggering a display list fallback |
| 482 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, IntRect(I
ntPoint(0, 0), sourceSize), defaultOptions); | 482 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, IntRect(I
ntPoint(0, 0), sourceSize), defaultOptions); |
| 483 | 483 |
| 484 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); | 484 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); |
| 485 EXPECT_FALSE(exceptionState.hadException()); | 485 EXPECT_FALSE(exceptionState.hadException()); |
| 486 | 486 |
| 487 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 487 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 488 } | 488 } |
| 489 | 489 |
| 490 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderExpensivePathPointCoun
t) | 490 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderExpensivePathPointCoun
t) |
| 491 { | 491 { |
| 492 createContext(NonOpaque); | 492 createContext(NonOpaque); |
| 493 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 493 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 494 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 494 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 495 | 495 |
| 496 context2d()->beginPath(); | 496 context2d()->beginPath(); |
| 497 context2d()->moveTo(7, 5); | 497 context2d()->moveTo(7, 5); |
| 498 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt-1; i++) { | 498 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt-1; i++) { |
| 499 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount - 1); | 499 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount - 1); |
| 500 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); | 500 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); |
| 501 } | 501 } |
| 502 context2d()->fill(); | 502 context2d()->fill(); |
| 503 | 503 |
| 504 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 504 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 505 } | 505 } |
| 506 | 506 |
| 507 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverExpensivePathPointCount) | 507 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverExpensivePathPointCount) |
| 508 { | 508 { |
| 509 createContext(NonOpaque); | 509 createContext(NonOpaque); |
| 510 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 510 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 511 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 511 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 512 | 512 |
| 513 context2d()->beginPath(); | 513 context2d()->beginPath(); |
| 514 context2d()->moveTo(7, 5); | 514 context2d()->moveTo(7, 5); |
| 515 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt + 1; i++) { | 515 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt + 1; i++) { |
| 516 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount + 1); | 516 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount + 1); |
| 517 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); | 517 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); |
| 518 } | 518 } |
| 519 context2d()->fill(); | 519 context2d()->fill(); |
| 520 | 520 |
| 521 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 521 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 522 } | 522 } |
| 523 | 523 |
| 524 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) | 524 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) |
| 525 { | 525 { |
| 526 createContext(NonOpaque); | 526 createContext(NonOpaque); |
| 527 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 527 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 528 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 528 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 529 | 529 |
| 530 context2d()->beginPath(); | 530 context2d()->beginPath(); |
| 531 context2d()->moveTo(1, 1); | 531 context2d()->moveTo(1, 1); |
| 532 context2d()->lineTo(5, 5); | 532 context2d()->lineTo(5, 5); |
| 533 context2d()->lineTo(9, 1); | 533 context2d()->lineTo(9, 1); |
| 534 context2d()->lineTo(5, 9); | 534 context2d()->lineTo(5, 9); |
| 535 context2d()->fill(); | 535 context2d()->fill(); |
| 536 | 536 |
| 537 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive) { | 537 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive) { |
| 538 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 538 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 539 } else { | 539 } else { |
| 540 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 540 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 | 543 |
| 544 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) | 544 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) |
| 545 { | 545 { |
| 546 createContext(NonOpaque); | 546 createContext(NonOpaque); |
| 547 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 547 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 548 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 548 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 549 | 549 |
| 550 context2d()->beginPath(); | 550 context2d()->beginPath(); |
| 551 context2d()->rect(1, 1, 2, 2); | 551 context2d()->rect(1, 1, 2, 2); |
| 552 context2d()->clip(); | 552 context2d()->clip(); |
| 553 context2d()->fillRect(0, 0, 4, 4); | 553 context2d()->fillRect(0, 0, 4, 4); |
| 554 | 554 |
| 555 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 555 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 556 } | 556 } |
| 557 | 557 |
| 558 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) | 558 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) |
| 559 { | 559 { |
| 560 createContext(NonOpaque); | 560 createContext(NonOpaque); |
| 561 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 561 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 562 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 562 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 563 | 563 |
| 564 context2d()->beginPath(); | 564 context2d()->beginPath(); |
| 565 context2d()->moveTo(1, 1); | 565 context2d()->moveTo(1, 1); |
| 566 context2d()->lineTo(5, 5); | 566 context2d()->lineTo(5, 5); |
| 567 context2d()->lineTo(9, 1); | 567 context2d()->lineTo(9, 1); |
| 568 context2d()->lineTo(5, 9); | 568 context2d()->lineTo(5, 9); |
| 569 context2d()->clip(); | 569 context2d()->clip(); |
| 570 context2d()->fillRect(0, 0, 4, 4); | 570 context2d()->fillRect(0, 0, 4, 4); |
| 571 | 571 |
| 572 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive) { | 572 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive) { |
| 573 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 573 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 574 } else { | 574 } else { |
| 575 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 575 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 576 } | 576 } |
| 577 } | 577 } |
| 578 | 578 |
| 579 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) | 579 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) |
| 580 { | 580 { |
| 581 createContext(NonOpaque); | 581 createContext(NonOpaque); |
| 582 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 582 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 583 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 583 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 584 | 584 |
| 585 context2d()->setShadowColor(String("red")); | 585 context2d()->setShadowColor(String("red")); |
| 586 context2d()->setShadowBlur(1.0f); | 586 context2d()->setShadowBlur(1.0f); |
| 587 context2d()->fillRect(1, 1, 1, 1); | 587 context2d()->fillRect(1, 1, 1, 1); |
| 588 | 588 |
| 589 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive) { | 589 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive) { |
| 590 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 590 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 591 } else { | 591 } else { |
| 592 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 592 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 593 } | 593 } |
| 594 } | 594 } |
| 595 | 595 |
| 596 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) | 596 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) |
| 597 { | 597 { |
| 598 createContext(NonOpaque); | 598 createContext(NonOpaque); |
| 599 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 599 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 600 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 600 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 601 | 601 |
| 602 context2d()->setShadowColor(String("red")); | 602 context2d()->setShadowColor(String("red")); |
| 603 context2d()->setShadowOffsetX(1.0f); | 603 context2d()->setShadowOffsetX(1.0f); |
| 604 context2d()->fillRect(1, 1, 1, 1); | 604 context2d()->fillRect(1, 1, 1, 1); |
| 605 | 605 |
| 606 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 606 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 607 } | 607 } |
| 608 | 608 |
| 609 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) | 609 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) |
| 610 { | 610 { |
| 611 createContext(NonOpaque); | 611 createContext(NonOpaque); |
| 612 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 612 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 613 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 613 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 614 | 614 |
| 615 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 615 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 616 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth - 1; ++i) { | 616 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth - 1; ++i) { |
| 617 context2d()->save(); | 617 context2d()->save(); |
| 618 context2d()->translate(1.0f, 0.0f); | 618 context2d()->translate(1.0f, 0.0f); |
| 619 } | 619 } |
| 620 canvasElement().doDeferredPaintInvalidation(); // To close the current frame | 620 canvasElement().doDeferredPaintInvalidation(); // To close the current frame |
| 621 } | 621 } |
| 622 | 622 |
| 623 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) | 623 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) |
| 624 { | 624 { |
| 625 createContext(NonOpaque); | 625 createContext(NonOpaque); |
| 626 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tFallback), NonOpaque)); | 626 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tFallback), NonOpaque)); |
| 627 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 627 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 628 | 628 |
| 629 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 629 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 630 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth; ++i) { | 630 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth; ++i) { |
| 631 context2d()->save(); | 631 context2d()->save(); |
| 632 context2d()->translate(1.0f, 0.0f); | 632 context2d()->translate(1.0f, 0.0f); |
| 633 } | 633 } |
| 634 canvasElement().doDeferredPaintInvalidation(); // To close the current frame | 634 canvasElement().doDeferredPaintInvalidation(); // To close the current frame |
| 635 } | 635 } |
| 636 | 636 |
| 637 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) | 637 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) |
| 638 { | 638 { |
| 639 // Verify that drawing text to an opaque canvas, which is expected to | 639 // Verify that drawing text to an opaque canvas, which is expected to |
| 640 // render with subpixel text anti-aliasing, results in falling out | 640 // render with subpixel text anti-aliasing, results in falling out |
| 641 // of display list mode because the current diplay list implementation | 641 // of display list mode because the current diplay list implementation |
| 642 // does not support pixel geometry settings. | 642 // does not support pixel geometry settings. |
| 643 // See: crbug.com/583809 | 643 // See: crbug.com/583809 |
| 644 createContext(Opaque); | 644 createContext(Opaque); |
| 645 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tFallback), Opaque)); | 645 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tFallback), Opaque)); |
| 646 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 646 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 647 | 647 |
| 648 context2d()->fillText("Text", 0, 5); | 648 context2d()->fillText("Text", 0, 5); |
| 649 } | 649 } |
| 650 | 650 |
| 651 TEST_F(CanvasRenderingContext2DTest, NonOpaqueDisplayListDoesNotFallBackForText) | 651 TEST_F(CanvasRenderingContext2DTest, NonOpaqueDisplayListDoesNotFallBackForText) |
| 652 { | 652 { |
| 653 createContext(NonOpaque); | 653 createContext(NonOpaque); |
| 654 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); | 654 OwnPtr<RecordingImageBufferSurface> surface = adoptPtr(new RecordingImageBuf
ferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFactory::Expec
tNoFallback), NonOpaque)); |
| 655 canvasElement().createImageBufferUsingSurfaceForTesting(surface.release()); | 655 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 656 | 656 |
| 657 context2d()->fillText("Text", 0, 5); | 657 context2d()->fillText("Text", 0, 5); |
| 658 } | 658 } |
| 659 | 659 |
| 660 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) | 660 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) |
| 661 { | 661 { |
| 662 NonThrowableExceptionState nonThrowableExceptionState; | 662 NonThrowableExceptionState nonThrowableExceptionState; |
| 663 Element* canvasElement = document().createElement("canvas", nonThrowableExce
ptionState); | 663 Element* canvasElement = document().createElement("canvas", nonThrowableExce
ptionState); |
| 664 EXPECT_FALSE(nonThrowableExceptionState.hadException()); | 664 EXPECT_FALSE(nonThrowableExceptionState.hadException()); |
| 665 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(canvasElement); | 665 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(canvasElement); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 678 imageSource.setImageBitmap(imageBitmapDerived); | 678 imageSource.setImageBitmap(imageBitmapDerived); |
| 679 context->drawImage(canvas->getExecutionContext(), imageSource, 0, 0, excepti
onState); | 679 context->drawImage(canvas->getExecutionContext(), imageSource, 0, 0, excepti
onState); |
| 680 } | 680 } |
| 681 | 681 |
| 682 TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) | 682 TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) |
| 683 { | 683 { |
| 684 createContext(NonOpaque); | 684 createContext(NonOpaque); |
| 685 | 685 |
| 686 OwnPtr<FakeAcceleratedImageBufferSurfaceForTesting> fakeAccelerateSurface =
adoptPtr(new FakeAcceleratedImageBufferSurfaceForTesting(IntSize(10, 10), NonOpa
que)); | 686 OwnPtr<FakeAcceleratedImageBufferSurfaceForTesting> fakeAccelerateSurface =
adoptPtr(new FakeAcceleratedImageBufferSurfaceForTesting(IntSize(10, 10), NonOpa
que)); |
| 687 FakeAcceleratedImageBufferSurfaceForTesting* fakeAccelerateSurfacePtr = fake
AccelerateSurface.get(); | 687 FakeAcceleratedImageBufferSurfaceForTesting* fakeAccelerateSurfacePtr = fake
AccelerateSurface.get(); |
| 688 canvasElement().createImageBufferUsingSurfaceForTesting(fakeAccelerateSurfac
e.release()); | 688 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(fakeAccele
rateSurface)); |
| 689 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per p
ixel per buffer, | 689 // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per p
ixel per buffer, |
| 690 // and 2 is an estimate of num of gpu buffers required | 690 // and 2 is an estimate of num of gpu buffers required |
| 691 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); | 691 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); |
| 692 EXPECT_EQ(800, getGlobalGPUMemoryUsage()); | 692 EXPECT_EQ(800, getGlobalGPUMemoryUsage()); |
| 693 | 693 |
| 694 // Switching accelerated mode to non-accelerated mode | 694 // Switching accelerated mode to non-accelerated mode |
| 695 fakeAccelerateSurfacePtr->setIsAccelerated(false); | 695 fakeAccelerateSurfacePtr->setIsAccelerated(false); |
| 696 canvasElement().buffer()->updateGPUMemoryUsage(); | 696 canvasElement().buffer()->updateGPUMemoryUsage(); |
| 697 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); | 697 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); |
| 698 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); | 698 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); |
| 699 | 699 |
| 700 // Switching non-accelerated mode to accelerated mode | 700 // Switching non-accelerated mode to accelerated mode |
| 701 fakeAccelerateSurfacePtr->setIsAccelerated(true); | 701 fakeAccelerateSurfacePtr->setIsAccelerated(true); |
| 702 canvasElement().buffer()->updateGPUMemoryUsage(); | 702 canvasElement().buffer()->updateGPUMemoryUsage(); |
| 703 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); | 703 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); |
| 704 EXPECT_EQ(800, getGlobalGPUMemoryUsage()); | 704 EXPECT_EQ(800, getGlobalGPUMemoryUsage()); |
| 705 | 705 |
| 706 // Creating a different accelerated image buffer | 706 // Creating a different accelerated image buffer |
| 707 OwnPtr<FakeAcceleratedImageBufferSurfaceForTesting> fakeAccelerateSurface2 =
adoptPtr(new FakeAcceleratedImageBufferSurfaceForTesting(IntSize(10, 5), NonOpa
que)); | 707 OwnPtr<FakeAcceleratedImageBufferSurfaceForTesting> fakeAccelerateSurface2 =
adoptPtr(new FakeAcceleratedImageBufferSurfaceForTesting(IntSize(10, 5), NonOpa
que)); |
| 708 OwnPtr<ImageBuffer> imageBuffer2 = ImageBuffer::create(fakeAccelerateSurface
2.release()); | 708 OwnPtr<ImageBuffer> imageBuffer2 = ImageBuffer::create(std::move(fakeAcceler
ateSurface2)); |
| 709 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); | 709 EXPECT_EQ(800, getCurrentGPUMemoryUsage()); |
| 710 EXPECT_EQ(1200, getGlobalGPUMemoryUsage()); | 710 EXPECT_EQ(1200, getGlobalGPUMemoryUsage()); |
| 711 | 711 |
| 712 // Tear down the first image buffer that resides in current canvas element | 712 // Tear down the first image buffer that resides in current canvas element |
| 713 canvasElement().setSize(IntSize(20, 20)); | 713 canvasElement().setSize(IntSize(20, 20)); |
| 714 Mock::VerifyAndClearExpectations(fakeAccelerateSurfacePtr); | 714 Mock::VerifyAndClearExpectations(fakeAccelerateSurfacePtr); |
| 715 EXPECT_EQ(400, getGlobalGPUMemoryUsage()); | 715 EXPECT_EQ(400, getGlobalGPUMemoryUsage()); |
| 716 | 716 |
| 717 // Tear down the second image buffer | 717 // Tear down the second image buffer |
| 718 imageBuffer2.clear(); | 718 imageBuffer2.clear(); |
| 719 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); | 719 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); |
| 720 } | 720 } |
| 721 | 721 |
| 722 } // namespace blink | 722 } // namespace blink |
| OLD | NEW |