| 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/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/fetch/MemoryCache.h" | 8 #include "core/fetch/MemoryCache.h" |
| 9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
| 10 #include "core/frame/ImageBitmap.h" | 10 #include "core/frame/ImageBitmap.h" |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } | 179 } |
| 180 | 180 |
| 181 void CanvasRenderingContext2DTest::TearDown() | 181 void CanvasRenderingContext2DTest::TearDown() |
| 182 { | 182 { |
| 183 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); | 183 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); |
| 184 replaceMemoryCacheForTesting(m_globalMemoryCache.release()); | 184 replaceMemoryCacheForTesting(m_globalMemoryCache.release()); |
| 185 } | 185 } |
| 186 | 186 |
| 187 PassRefPtr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::makeBridge(std::un
ique_ptr<FakeWebGraphicsContext3DProvider> provider, const IntSize& size, Canvas
2DLayerBridge::AccelerationMode accelerationMode) | 187 PassRefPtr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::makeBridge(std::un
ique_ptr<FakeWebGraphicsContext3DProvider> provider, const IntSize& size, Canvas
2DLayerBridge::AccelerationMode accelerationMode) |
| 188 { | 188 { |
| 189 return adoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, NonOpa
que, accelerationMode)); | 189 return adoptRef(new Canvas2DLayerBridge(std::move(provider), size, 0, NonOpa
que, accelerationMode, nullptr)); |
| 190 } | 190 } |
| 191 | 191 |
| 192 //============================================================================ | 192 //============================================================================ |
| 193 | 193 |
| 194 class FakeAcceleratedImageBufferSurfaceForTesting : public UnacceleratedImageBuf
ferSurface { | 194 class FakeAcceleratedImageBufferSurfaceForTesting : public UnacceleratedImageBuf
ferSurface { |
| 195 public: | 195 public: |
| 196 FakeAcceleratedImageBufferSurfaceForTesting(const IntSize& size, OpacityMode
mode) | 196 FakeAcceleratedImageBufferSurfaceForTesting(const IntSize& size, OpacityMode
mode) |
| 197 : UnacceleratedImageBufferSurface(size, mode) | 197 : UnacceleratedImageBufferSurface(size, mode) |
| 198 , m_isAccelerated(true) { } | 198 , m_isAccelerated(true) { } |
| 199 ~FakeAcceleratedImageBufferSurfaceForTesting() override { } | 199 ~FakeAcceleratedImageBufferSurfaceForTesting() override { } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 //============================================================================ | 269 //============================================================================ |
| 270 | 270 |
| 271 class MockSurfaceFactory : public RecordingImageBufferFallbackSurfaceFactory { | 271 class MockSurfaceFactory : public RecordingImageBufferFallbackSurfaceFactory { |
| 272 public: | 272 public: |
| 273 enum FallbackExpectation { | 273 enum FallbackExpectation { |
| 274 ExpectFallback, | 274 ExpectFallback, |
| 275 ExpectNoFallback | 275 ExpectNoFallback |
| 276 }; | 276 }; |
| 277 static std::unique_ptr<MockSurfaceFactory> create(FallbackExpectation expect
ation) { return wrapUnique(new MockSurfaceFactory(expectation)); } | 277 static std::unique_ptr<MockSurfaceFactory> create(FallbackExpectation expect
ation) { return wrapUnique(new MockSurfaceFactory(expectation)); } |
| 278 | 278 |
| 279 std::unique_ptr<ImageBufferSurface> createSurface(const IntSize& size, Opaci
tyMode mode) override | 279 std::unique_ptr<ImageBufferSurface> createSurface(const IntSize& size, Opaci
tyMode mode, sk_sp<SkColorSpace> colorSpace) override |
| 280 { | 280 { |
| 281 EXPECT_EQ(ExpectFallback, m_expectation); | 281 EXPECT_EQ(ExpectFallback, m_expectation); |
| 282 m_didFallback = true; | 282 m_didFallback = true; |
| 283 return wrapUnique(new UnacceleratedImageBufferSurface(size, mode)); | 283 return wrapUnique(new UnacceleratedImageBufferSurface(size, mode, Initia
lizeImagePixels, colorSpace)); |
| 284 } | 284 } |
| 285 | 285 |
| 286 ~MockSurfaceFactory() override | 286 ~MockSurfaceFactory() override |
| 287 { | 287 { |
| 288 if (m_expectation == ExpectFallback) { | 288 if (m_expectation == ExpectFallback) { |
| 289 EXPECT_TRUE(m_didFallback); | 289 EXPECT_TRUE(m_didFallback); |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 | 292 |
| 293 private: | 293 private: |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 // Test composite operators with an opaque rect that does not cover the enti
re canvas | 413 // Test composite operators with an opaque rect that does not cover the enti
re canvas |
| 414 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("clear")), fillRect(0,
0, 5, 5)); | 414 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("clear")), fillRect(0,
0, 5, 5)); |
| 415 TEST_OVERDRAW_2(1, setGlobalCompositeOperation(String("copy")), fillRect(0,
0, 5, 5)); | 415 TEST_OVERDRAW_2(1, setGlobalCompositeOperation(String("copy")), fillRect(0,
0, 5, 5)); |
| 416 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), fillR
ect(0, 0, 5, 5)); | 416 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-over")), fillR
ect(0, 0, 5, 5)); |
| 417 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), fillRec
t(0, 0, 5, 5)); | 417 TEST_OVERDRAW_2(0, setGlobalCompositeOperation(String("source-in")), fillRec
t(0, 0, 5, 5)); |
| 418 } | 418 } |
| 419 | 419 |
| 420 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) | 420 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionByDefault) |
| 421 { | 421 { |
| 422 createContext(NonOpaque); | 422 createContext(NonOpaque); |
| 423 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 423 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 424 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 424 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 425 | 425 |
| 426 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 426 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 427 } | 427 } |
| 428 | 428 |
| 429 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) | 429 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderOverdrawLimit) |
| 430 { | 430 { |
| 431 createContext(NonOpaque); | 431 createContext(NonOpaque); |
| 432 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 432 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 433 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 433 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 434 | 434 |
| 435 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 435 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 436 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold - 1; i++) { | 436 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold - 1; i++) { |
| 437 context2d()->fillRect(0, 0, 10, 10); | 437 context2d()->fillRect(0, 0, 10, 10); |
| 438 } | 438 } |
| 439 | 439 |
| 440 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 440 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 441 } | 441 } |
| 442 | 442 |
| 443 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) | 443 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverOverdrawLimit) |
| 444 { | 444 { |
| 445 createContext(NonOpaque); | 445 createContext(NonOpaque); |
| 446 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 446 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 447 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 447 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 448 | 448 |
| 449 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization | 449 context2d()->setGlobalAlpha(0.5f); // To prevent overdraw optimization |
| 450 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold; i++) { | 450 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThr
eshold; i++) { |
| 451 context2d()->fillRect(0, 0, 10, 10); | 451 context2d()->fillRect(0, 0, 10, 10); |
| 452 } | 452 } |
| 453 | 453 |
| 454 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 454 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 455 } | 455 } |
| 456 | 456 |
| 457 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) | 457 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderImageSizeRatioLimit) |
| 458 { | 458 { |
| 459 createContext(NonOpaque); | 459 createContext(NonOpaque); |
| 460 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 460 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 461 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 461 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 462 | 462 |
| 463 NonThrowableExceptionState exceptionState; | 463 NonThrowableExceptionState exceptionState; |
| 464 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); | 464 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); |
| 465 EXPECT_FALSE(exceptionState.hadException()); | 465 EXPECT_FALSE(exceptionState.hadException()); |
| 466 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); | 466 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); |
| 467 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio); | 467 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio); |
| 468 std::unique_ptr<UnacceleratedImageBufferSurface> sourceSurface = wrapUnique(
new UnacceleratedImageBufferSurface(sourceSize, NonOpaque)); | 468 std::unique_ptr<UnacceleratedImageBufferSurface> sourceSurface = wrapUnique(
new UnacceleratedImageBufferSurface(sourceSize, NonOpaque)); |
| 469 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); | 469 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); |
| 470 | 470 |
| 471 const ImageBitmapOptions defaultOptions; | 471 const ImageBitmapOptions defaultOptions; |
| 472 Optional<IntRect> cropRect = IntRect(IntPoint(0, 0), sourceSize); | 472 Optional<IntRect> cropRect = IntRect(IntPoint(0, 0), sourceSize); |
| 473 // Go through an ImageBitmap to avoid triggering a display list fallback | 473 // Go through an ImageBitmap to avoid triggering a display list fallback |
| 474 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, cropRect,
defaultOptions); | 474 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, cropRect,
defaultOptions); |
| 475 | 475 |
| 476 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); | 476 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); |
| 477 EXPECT_FALSE(exceptionState.hadException()); | 477 EXPECT_FALSE(exceptionState.hadException()); |
| 478 | 478 |
| 479 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 479 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 480 } | 480 } |
| 481 | 481 |
| 482 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) | 482 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverImageSizeRatioLimit) |
| 483 { | 483 { |
| 484 createContext(NonOpaque); | 484 createContext(NonOpaque); |
| 485 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 485 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 486 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 486 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 487 | 487 |
| 488 NonThrowableExceptionState exceptionState; | 488 NonThrowableExceptionState exceptionState; |
| 489 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); | 489 Element* sourceCanvasElement = document().createElement("canvas", exceptionS
tate); |
| 490 EXPECT_FALSE(exceptionState.hadException()); | 490 EXPECT_FALSE(exceptionState.hadException()); |
| 491 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); | 491 HTMLCanvasElement* sourceCanvas = static_cast<HTMLCanvasElement*>(sourceCanv
asElement); |
| 492 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio + 1); | 492 IntSize sourceSize(10, 10 * ExpensiveCanvasHeuristicParameters::ExpensiveIma
geSizeRatio + 1); |
| 493 std::unique_ptr<UnacceleratedImageBufferSurface> sourceSurface = wrapUnique(
new UnacceleratedImageBufferSurface(sourceSize, NonOpaque)); | 493 std::unique_ptr<UnacceleratedImageBufferSurface> sourceSurface = wrapUnique(
new UnacceleratedImageBufferSurface(sourceSize, NonOpaque)); |
| 494 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); | 494 sourceCanvas->createImageBufferUsingSurfaceForTesting(std::move(sourceSurfac
e)); |
| 495 | 495 |
| 496 const ImageBitmapOptions defaultOptions; | 496 const ImageBitmapOptions defaultOptions; |
| 497 Optional<IntRect> cropRect = IntRect(IntPoint(0, 0), sourceSize); | 497 Optional<IntRect> cropRect = IntRect(IntPoint(0, 0), sourceSize); |
| 498 // Go through an ImageBitmap to avoid triggering a display list fallback | 498 // Go through an ImageBitmap to avoid triggering a display list fallback |
| 499 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, cropRect,
defaultOptions); | 499 ImageBitmap* sourceImageBitmap = ImageBitmap::create(sourceCanvas, cropRect,
defaultOptions); |
| 500 | 500 |
| 501 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); | 501 context2d()->drawImage(canvasElement().getExecutionContext(), sourceImageBit
map, 0, 0, 1, 1, 0, 0, 1, 1, exceptionState); |
| 502 EXPECT_FALSE(exceptionState.hadException()); | 502 EXPECT_FALSE(exceptionState.hadException()); |
| 503 | 503 |
| 504 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 504 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 505 } | 505 } |
| 506 | 506 |
| 507 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderExpensivePathPointCoun
t) | 507 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionUnderExpensivePathPointCoun
t) |
| 508 { | 508 { |
| 509 createContext(NonOpaque); | 509 createContext(NonOpaque); |
| 510 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 510 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 511 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 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_FALSE(canvasElement().shouldBeDirectComposited()); | 521 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 522 } | 522 } |
| 523 | 523 |
| 524 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverExpensivePathPointCount) | 524 TEST_F(CanvasRenderingContext2DTest, LayerPromotionOverExpensivePathPointCount) |
| 525 { | 525 { |
| 526 createContext(NonOpaque); | 526 createContext(NonOpaque); |
| 527 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 527 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 528 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 528 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 529 | 529 |
| 530 context2d()->beginPath(); | 530 context2d()->beginPath(); |
| 531 context2d()->moveTo(7, 5); | 531 context2d()->moveTo(7, 5); |
| 532 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt + 1; i++) { | 532 for (int i = 1; i < ExpensiveCanvasHeuristicParameters::ExpensivePathPointCo
unt + 1; i++) { |
| 533 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount + 1); | 533 float angleRad = twoPiFloat * i / (ExpensiveCanvasHeuristicParameters::E
xpensivePathPointCount + 1); |
| 534 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); | 534 context2d()->lineTo(5 + 2 * cos(angleRad), 5 + 2 * sin(angleRad)); |
| 535 } | 535 } |
| 536 context2d()->fill(); | 536 context2d()->fill(); |
| 537 | 537 |
| 538 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 538 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 539 } | 539 } |
| 540 | 540 |
| 541 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) | 541 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWhenPathIsConcave) |
| 542 { | 542 { |
| 543 createContext(NonOpaque); | 543 createContext(NonOpaque); |
| 544 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 544 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 545 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 545 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 546 | 546 |
| 547 context2d()->beginPath(); | 547 context2d()->beginPath(); |
| 548 context2d()->moveTo(1, 1); | 548 context2d()->moveTo(1, 1); |
| 549 context2d()->lineTo(5, 5); | 549 context2d()->lineTo(5, 5); |
| 550 context2d()->lineTo(9, 1); | 550 context2d()->lineTo(9, 1); |
| 551 context2d()->lineTo(5, 9); | 551 context2d()->lineTo(5, 9); |
| 552 context2d()->fill(); | 552 context2d()->fill(); |
| 553 | 553 |
| 554 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive) { | 554 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive) { |
| 555 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 555 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 556 } else { | 556 } else { |
| 557 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 557 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 558 } | 558 } |
| 559 } | 559 } |
| 560 | 560 |
| 561 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) | 561 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithRectangleClip) |
| 562 { | 562 { |
| 563 createContext(NonOpaque); | 563 createContext(NonOpaque); |
| 564 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 564 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 565 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 565 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 566 | 566 |
| 567 context2d()->beginPath(); | 567 context2d()->beginPath(); |
| 568 context2d()->rect(1, 1, 2, 2); | 568 context2d()->rect(1, 1, 2, 2); |
| 569 context2d()->clip(); | 569 context2d()->clip(); |
| 570 context2d()->fillRect(0, 0, 4, 4); | 570 context2d()->fillRect(0, 0, 4, 4); |
| 571 | 571 |
| 572 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 572 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 573 } | 573 } |
| 574 | 574 |
| 575 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) | 575 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithComplexClip) |
| 576 { | 576 { |
| 577 createContext(NonOpaque); | 577 createContext(NonOpaque); |
| 578 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 578 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 579 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 579 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 580 | 580 |
| 581 context2d()->beginPath(); | 581 context2d()->beginPath(); |
| 582 context2d()->moveTo(1, 1); | 582 context2d()->moveTo(1, 1); |
| 583 context2d()->lineTo(5, 5); | 583 context2d()->lineTo(5, 5); |
| 584 context2d()->lineTo(9, 1); | 584 context2d()->lineTo(9, 1); |
| 585 context2d()->lineTo(5, 9); | 585 context2d()->lineTo(5, 9); |
| 586 context2d()->clip(); | 586 context2d()->clip(); |
| 587 context2d()->fillRect(0, 0, 4, 4); | 587 context2d()->fillRect(0, 0, 4, 4); |
| 588 | 588 |
| 589 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive) { | 589 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive) { |
| 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, LayerPromotionWithBlurredShadow) | 596 TEST_F(CanvasRenderingContext2DTest, LayerPromotionWithBlurredShadow) |
| 597 { | 597 { |
| 598 createContext(NonOpaque); | 598 createContext(NonOpaque); |
| 599 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 599 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 600 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 600 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 601 | 601 |
| 602 context2d()->setShadowColor(String("red")); | 602 context2d()->setShadowColor(String("red")); |
| 603 context2d()->setShadowBlur(1.0f); | 603 context2d()->setShadowBlur(1.0f); |
| 604 context2d()->fillRect(1, 1, 1, 1); | 604 context2d()->fillRect(1, 1, 1, 1); |
| 605 | 605 |
| 606 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive) { | 606 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive) { |
| 607 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); | 607 EXPECT_TRUE(canvasElement().shouldBeDirectComposited()); |
| 608 } else { | 608 } else { |
| 609 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 609 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 610 } | 610 } |
| 611 } | 611 } |
| 612 | 612 |
| 613 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) | 613 TEST_F(CanvasRenderingContext2DTest, NoLayerPromotionWithSharpShadow) |
| 614 { | 614 { |
| 615 createContext(NonOpaque); | 615 createContext(NonOpaque); |
| 616 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 616 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 617 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 617 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 618 | 618 |
| 619 context2d()->setShadowColor(String("red")); | 619 context2d()->setShadowColor(String("red")); |
| 620 context2d()->setShadowOffsetX(1.0f); | 620 context2d()->setShadowOffsetX(1.0f); |
| 621 context2d()->fillRect(1, 1, 1, 1); | 621 context2d()->fillRect(1, 1, 1, 1); |
| 622 | 622 |
| 623 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); | 623 EXPECT_FALSE(canvasElement().shouldBeDirectComposited()); |
| 624 } | 624 } |
| 625 | 625 |
| 626 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) | 626 TEST_F(CanvasRenderingContext2DTest, NoFallbackWithSmallState) |
| 627 { | 627 { |
| 628 createContext(NonOpaque); | 628 createContext(NonOpaque); |
| 629 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 629 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 630 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 630 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 631 | 631 |
| 632 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 632 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 633 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth - 1; ++i) { | 633 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth - 1; ++i) { |
| 634 context2d()->save(); | 634 context2d()->save(); |
| 635 context2d()->translate(1.0f, 0.0f); | 635 context2d()->translate(1.0f, 0.0f); |
| 636 } | 636 } |
| 637 canvasElement().doDeferredPaintInvalidation(); // To close the current frame | 637 canvasElement().doDeferredPaintInvalidation(); // To close the current frame |
| 638 } | 638 } |
| 639 | 639 |
| 640 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) | 640 TEST_F(CanvasRenderingContext2DTest, FallbackWithLargeState) |
| 641 { | 641 { |
| 642 createContext(NonOpaque); | 642 createContext(NonOpaque); |
| 643 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectFallback), NonOpaque)); | 643 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectFallback), NonOpaque, nullptr)); |
| 644 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 644 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 645 | 645 |
| 646 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect | 646 context2d()->fillRect(0, 0, 1, 1); // To have a non-empty dirty rect |
| 647 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth; ++i) { | 647 for (int i = 0; i < ExpensiveCanvasHeuristicParameters::ExpensiveRecordingSt
ackDepth; ++i) { |
| 648 context2d()->save(); | 648 context2d()->save(); |
| 649 context2d()->translate(1.0f, 0.0f); | 649 context2d()->translate(1.0f, 0.0f); |
| 650 } | 650 } |
| 651 canvasElement().doDeferredPaintInvalidation(); // To close the current frame | 651 canvasElement().doDeferredPaintInvalidation(); // To close the current frame |
| 652 } | 652 } |
| 653 | 653 |
| 654 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) | 654 TEST_F(CanvasRenderingContext2DTest, OpaqueDisplayListFallsBackForText) |
| 655 { | 655 { |
| 656 // Verify that drawing text to an opaque canvas, which is expected to | 656 // Verify that drawing text to an opaque canvas, which is expected to |
| 657 // render with subpixel text anti-aliasing, results in falling out | 657 // render with subpixel text anti-aliasing, results in falling out |
| 658 // of display list mode because the current diplay list implementation | 658 // of display list mode because the current diplay list implementation |
| 659 // does not support pixel geometry settings. | 659 // does not support pixel geometry settings. |
| 660 // See: crbug.com/583809 | 660 // See: crbug.com/583809 |
| 661 createContext(Opaque); | 661 createContext(Opaque); |
| 662 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectFallback), Opaque)); | 662 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectFallback), Opaque, nullptr)); |
| 663 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 663 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 664 | 664 |
| 665 context2d()->fillText("Text", 0, 5); | 665 context2d()->fillText("Text", 0, 5); |
| 666 } | 666 } |
| 667 | 667 |
| 668 TEST_F(CanvasRenderingContext2DTest, NonOpaqueDisplayListDoesNotFallBackForText) | 668 TEST_F(CanvasRenderingContext2DTest, NonOpaqueDisplayListDoesNotFallBackForText) |
| 669 { | 669 { |
| 670 createContext(NonOpaque); | 670 createContext(NonOpaque); |
| 671 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque)); | 671 std::unique_ptr<RecordingImageBufferSurface> surface = wrapUnique(new Record
ingImageBufferSurface(IntSize(10, 10), MockSurfaceFactory::create(MockSurfaceFac
tory::ExpectNoFallback), NonOpaque, nullptr)); |
| 672 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); | 672 canvasElement().createImageBufferUsingSurfaceForTesting(std::move(surface)); |
| 673 | 673 |
| 674 context2d()->fillText("Text", 0, 5); | 674 context2d()->fillText("Text", 0, 5); |
| 675 } | 675 } |
| 676 | 676 |
| 677 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) | 677 TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) |
| 678 { | 678 { |
| 679 NonThrowableExceptionState nonThrowableExceptionState; | 679 NonThrowableExceptionState nonThrowableExceptionState; |
| 680 Element* canvasElement = document().createElement("canvas", nonThrowableExce
ptionState); | 680 Element* canvasElement = document().createElement("canvas", nonThrowableExce
ptionState); |
| 681 EXPECT_FALSE(nonThrowableExceptionState.hadException()); | 681 EXPECT_FALSE(nonThrowableExceptionState.hadException()); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 EXPECT_FALSE(canvasElement().buffer()->isAccelerated()); | 854 EXPECT_FALSE(canvasElement().buffer()->isAccelerated()); |
| 855 | 855 |
| 856 context->fillRect(10, 10, 100, 100); | 856 context->fillRect(10, 10, 100, 100); |
| 857 | 857 |
| 858 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); | 858 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); |
| 859 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); | 859 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); |
| 860 EXPECT_EQ(0u, getGlobalAcceleratedImageBufferCount()); | 860 EXPECT_EQ(0u, getGlobalAcceleratedImageBufferCount()); |
| 861 } | 861 } |
| 862 | 862 |
| 863 } // namespace blink | 863 } // namespace blink |
| OLD | NEW |