| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/BaseRenderingContext2D.h" | 5 #include "modules/canvas2d/BaseRenderingContext2D.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionMessages.h" | 7 #include "bindings/core/v8/ExceptionMessages.h" |
| 8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 9 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 10 #include "core/css/cssom/CSSURLImageValue.h" | 10 #include "core/css/cssom/CSSURLImageValue.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "modules/canvas2d/Path2D.h" | 21 #include "modules/canvas2d/Path2D.h" |
| 22 #include "platform/Histogram.h" | 22 #include "platform/Histogram.h" |
| 23 #include "platform/RuntimeEnabledFeatures.h" | 23 #include "platform/RuntimeEnabledFeatures.h" |
| 24 #include "platform/geometry/FloatQuad.h" | 24 #include "platform/geometry/FloatQuad.h" |
| 25 #include "platform/graphics/Color.h" | 25 #include "platform/graphics/Color.h" |
| 26 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" | 26 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" |
| 27 #include "platform/graphics/Image.h" | 27 #include "platform/graphics/Image.h" |
| 28 #include "platform/graphics/ImageBuffer.h" | 28 #include "platform/graphics/ImageBuffer.h" |
| 29 #include "platform/graphics/StrokeData.h" | 29 #include "platform/graphics/StrokeData.h" |
| 30 #include "platform/graphics/skia/SkiaUtils.h" | 30 #include "platform/graphics/skia/SkiaUtils.h" |
| 31 #include "skia/ext/cdl_canvas.h" |
| 32 #include "skia/ext/cdl_paint.h" |
| 31 | 33 |
| 32 namespace blink { | 34 namespace blink { |
| 33 | 35 |
| 34 BaseRenderingContext2D::BaseRenderingContext2D() | 36 BaseRenderingContext2D::BaseRenderingContext2D() |
| 35 : m_clipAntialiasing(NotAntiAliased) { | 37 : m_clipAntialiasing(NotAntiAliased) { |
| 36 m_stateStack.append(CanvasRenderingContext2DState::create()); | 38 m_stateStack.append(CanvasRenderingContext2DState::create()); |
| 37 } | 39 } |
| 38 | 40 |
| 39 BaseRenderingContext2D::~BaseRenderingContext2D() {} | 41 BaseRenderingContext2D::~BaseRenderingContext2D() {} |
| 40 | 42 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 52 m_stateStack.back()->restore(); | 54 m_stateStack.back()->restore(); |
| 53 m_stateStack.append(CanvasRenderingContext2DState::create( | 55 m_stateStack.append(CanvasRenderingContext2DState::create( |
| 54 state(), CanvasRenderingContext2DState::DontCopyClipList)); | 56 state(), CanvasRenderingContext2DState::DontCopyClipList)); |
| 55 // Set the new state's unrealized count to 0, because it has no outstanding | 57 // Set the new state's unrealized count to 0, because it has no outstanding |
| 56 // saves. | 58 // saves. |
| 57 // We need to do this explicitly because the copy constructor and operator= | 59 // We need to do this explicitly because the copy constructor and operator= |
| 58 // used by the Vector operations copy the unrealized count from the previous | 60 // used by the Vector operations copy the unrealized count from the previous |
| 59 // state (in turn necessary to support correct resizing and unwinding of the | 61 // state (in turn necessary to support correct resizing and unwinding of the |
| 60 // stack). | 62 // stack). |
| 61 m_stateStack.back()->resetUnrealizedSaveCount(); | 63 m_stateStack.back()->resetUnrealizedSaveCount(); |
| 62 SkCanvas* canvas = drawingCanvas(); | 64 CdlCanvas* canvas = drawingCanvas(); |
| 63 if (canvas) | 65 if (canvas) |
| 64 canvas->save(); | 66 canvas->save(); |
| 65 validateStateStack(); | 67 validateStateStack(); |
| 66 } | 68 } |
| 67 } | 69 } |
| 68 | 70 |
| 69 void BaseRenderingContext2D::save() { | 71 void BaseRenderingContext2D::save() { |
| 70 m_stateStack.back()->save(); | 72 m_stateStack.back()->save(); |
| 71 } | 73 } |
| 72 | 74 |
| 73 void BaseRenderingContext2D::restore() { | 75 void BaseRenderingContext2D::restore() { |
| 74 validateStateStack(); | 76 validateStateStack(); |
| 75 if (state().hasUnrealizedSaves()) { | 77 if (state().hasUnrealizedSaves()) { |
| 76 // We never realized the save, so just record that it was unnecessary. | 78 // We never realized the save, so just record that it was unnecessary. |
| 77 m_stateStack.back()->restore(); | 79 m_stateStack.back()->restore(); |
| 78 return; | 80 return; |
| 79 } | 81 } |
| 80 ASSERT(m_stateStack.size() >= 1); | 82 ASSERT(m_stateStack.size() >= 1); |
| 81 if (m_stateStack.size() <= 1) | 83 if (m_stateStack.size() <= 1) |
| 82 return; | 84 return; |
| 83 m_path.transform(state().transform()); | 85 m_path.transform(state().transform()); |
| 84 m_stateStack.pop_back(); | 86 m_stateStack.pop_back(); |
| 85 m_stateStack.back()->clearResolvedFilter(); | 87 m_stateStack.back()->clearResolvedFilter(); |
| 86 m_path.transform(state().transform().inverse()); | 88 m_path.transform(state().transform().inverse()); |
| 87 SkCanvas* c = drawingCanvas(); | 89 CdlCanvas* c = drawingCanvas(); |
| 88 if (c) | 90 if (c) |
| 89 c->restore(); | 91 c->restore(); |
| 90 | 92 |
| 91 validateStateStack(); | 93 validateStateStack(); |
| 92 } | 94 } |
| 93 | 95 |
| 94 void BaseRenderingContext2D::restoreMatrixClipStack(SkCanvas* c) const { | 96 void BaseRenderingContext2D::restoreMatrixClipStack(CdlCanvas* c) const { |
| 95 if (!c) | 97 if (!c) |
| 96 return; | 98 return; |
| 97 HeapVector<Member<CanvasRenderingContext2DState>>::const_iterator currState; | 99 HeapVector<Member<CanvasRenderingContext2DState>>::const_iterator currState; |
| 98 DCHECK(m_stateStack.begin() < m_stateStack.end()); | 100 DCHECK(m_stateStack.begin() < m_stateStack.end()); |
| 99 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); | 101 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); |
| 100 currState++) { | 102 currState++) { |
| 101 CHECK(currState->get()); | 103 CHECK(currState->get()); |
| 102 c->setMatrix(SkMatrix::I()); | 104 c->setMatrix(SkMatrix::I()); |
| 103 currState->get()->playbackClips(c); | 105 currState->get()->playbackClips(c); |
| 104 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform())); | 106 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform())); |
| 105 c->save(); | 107 c->save(); |
| 106 } | 108 } |
| 107 c->restore(); | 109 c->restore(); |
| 108 validateStateStack(); | 110 validateStateStack(); |
| 109 } | 111 } |
| 110 | 112 |
| 111 void BaseRenderingContext2D::unwindStateStack() { | 113 void BaseRenderingContext2D::unwindStateStack() { |
| 112 if (size_t stackSize = m_stateStack.size()) { | 114 if (size_t stackSize = m_stateStack.size()) { |
| 113 if (SkCanvas* skCanvas = existingDrawingCanvas()) { | 115 if (CdlCanvas* skCanvas = existingDrawingCanvas()) { |
| 114 while (--stackSize) | 116 while (--stackSize) |
| 115 skCanvas->restore(); | 117 skCanvas->restore(); |
| 116 } | 118 } |
| 117 } | 119 } |
| 118 } | 120 } |
| 119 | 121 |
| 120 void BaseRenderingContext2D::reset() { | 122 void BaseRenderingContext2D::reset() { |
| 121 validateStateStack(); | 123 validateStateStack(); |
| 122 unwindStateStack(); | 124 unwindStateStack(); |
| 123 m_stateStack.resize(1); | 125 m_stateStack.resize(1); |
| 124 m_stateStack.front() = CanvasRenderingContext2DState::create(); | 126 m_stateStack.front() = CanvasRenderingContext2DState::create(); |
| 125 m_path.clear(); | 127 m_path.clear(); |
| 126 if (SkCanvas* c = existingDrawingCanvas()) { | 128 if (CdlCanvas* c = existingDrawingCanvas()) { |
| 127 // The canvas should always have an initial/unbalanced save frame, which | 129 // The canvas should always have an initial/unbalanced save frame, which |
| 128 // we use to reset the top level matrix and clip here. | 130 // we use to reset the top level matrix and clip here. |
| 129 DCHECK_EQ(c->getSaveCount(), 2); | 131 DCHECK_EQ(c->getSaveCount(), 2); |
| 130 c->restore(); | 132 c->restore(); |
| 131 c->save(); | 133 c->save(); |
| 132 DCHECK(c->getTotalMatrix().isIdentity()); | 134 DCHECK(c->getTotalMatrix().isIdentity()); |
| 133 #if DCHECK_IS_ON() | 135 #if DCHECK_IS_ON() |
| 134 SkIRect clipBounds; | 136 SkIRect clipBounds; |
| 135 DCHECK(c->getClipDeviceBounds(&clipBounds)); | 137 DCHECK(c->getClipDeviceBounds(&clipBounds)); |
| 136 DCHECK(clipBounds == c->imageInfo().bounds()); | 138 DCHECK(clipBounds == c->imageInfo().bounds()); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 } | 420 } |
| 419 | 421 |
| 420 void BaseRenderingContext2D::setCurrentTransform( | 422 void BaseRenderingContext2D::setCurrentTransform( |
| 421 SVGMatrixTearOff* matrixTearOff) { | 423 SVGMatrixTearOff* matrixTearOff) { |
| 422 const AffineTransform& transform = matrixTearOff->value(); | 424 const AffineTransform& transform = matrixTearOff->value(); |
| 423 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), | 425 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), |
| 424 transform.e(), transform.f()); | 426 transform.e(), transform.f()); |
| 425 } | 427 } |
| 426 | 428 |
| 427 void BaseRenderingContext2D::scale(double sx, double sy) { | 429 void BaseRenderingContext2D::scale(double sx, double sy) { |
| 428 SkCanvas* c = drawingCanvas(); | 430 CdlCanvas* c = drawingCanvas(); |
| 429 if (!c) | 431 if (!c) |
| 430 return; | 432 return; |
| 431 | 433 |
| 432 if (!std::isfinite(sx) || !std::isfinite(sy)) | 434 if (!std::isfinite(sx) || !std::isfinite(sy)) |
| 433 return; | 435 return; |
| 434 | 436 |
| 435 AffineTransform newTransform = state().transform(); | 437 AffineTransform newTransform = state().transform(); |
| 436 newTransform.scaleNonUniform(sx, sy); | 438 newTransform.scaleNonUniform(sx, sy); |
| 437 if (state().transform() == newTransform) | 439 if (state().transform() == newTransform) |
| 438 return; | 440 return; |
| 439 | 441 |
| 440 modifiableState().setTransform(newTransform); | 442 modifiableState().setTransform(newTransform); |
| 441 if (!state().isTransformInvertible()) | 443 if (!state().isTransformInvertible()) |
| 442 return; | 444 return; |
| 443 | 445 |
| 444 c->scale(sx, sy); | 446 c->scale(sx, sy); |
| 445 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy)); | 447 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy)); |
| 446 } | 448 } |
| 447 | 449 |
| 448 void BaseRenderingContext2D::rotate(double angleInRadians) { | 450 void BaseRenderingContext2D::rotate(double angleInRadians) { |
| 449 SkCanvas* c = drawingCanvas(); | 451 CdlCanvas* c = drawingCanvas(); |
| 450 if (!c) | 452 if (!c) |
| 451 return; | 453 return; |
| 452 | 454 |
| 453 if (!std::isfinite(angleInRadians)) | 455 if (!std::isfinite(angleInRadians)) |
| 454 return; | 456 return; |
| 455 | 457 |
| 456 AffineTransform newTransform = state().transform(); | 458 AffineTransform newTransform = state().transform(); |
| 457 newTransform.rotateRadians(angleInRadians); | 459 newTransform.rotateRadians(angleInRadians); |
| 458 if (state().transform() == newTransform) | 460 if (state().transform() == newTransform) |
| 459 return; | 461 return; |
| 460 | 462 |
| 461 modifiableState().setTransform(newTransform); | 463 modifiableState().setTransform(newTransform); |
| 462 if (!state().isTransformInvertible()) | 464 if (!state().isTransformInvertible()) |
| 463 return; | 465 return; |
| 464 c->rotate(angleInRadians * (180.0 / piFloat)); | 466 c->rotate(angleInRadians * (180.0 / piFloat)); |
| 465 m_path.transform(AffineTransform().rotateRadians(-angleInRadians)); | 467 m_path.transform(AffineTransform().rotateRadians(-angleInRadians)); |
| 466 } | 468 } |
| 467 | 469 |
| 468 void BaseRenderingContext2D::translate(double tx, double ty) { | 470 void BaseRenderingContext2D::translate(double tx, double ty) { |
| 469 SkCanvas* c = drawingCanvas(); | 471 CdlCanvas* c = drawingCanvas(); |
| 470 if (!c) | 472 if (!c) |
| 471 return; | 473 return; |
| 472 if (!state().isTransformInvertible()) | 474 if (!state().isTransformInvertible()) |
| 473 return; | 475 return; |
| 474 | 476 |
| 475 if (!std::isfinite(tx) || !std::isfinite(ty)) | 477 if (!std::isfinite(tx) || !std::isfinite(ty)) |
| 476 return; | 478 return; |
| 477 | 479 |
| 478 AffineTransform newTransform = state().transform(); | 480 AffineTransform newTransform = state().transform(); |
| 479 newTransform.translate(tx, ty); | 481 newTransform.translate(tx, ty); |
| 480 if (state().transform() == newTransform) | 482 if (state().transform() == newTransform) |
| 481 return; | 483 return; |
| 482 | 484 |
| 483 modifiableState().setTransform(newTransform); | 485 modifiableState().setTransform(newTransform); |
| 484 if (!state().isTransformInvertible()) | 486 if (!state().isTransformInvertible()) |
| 485 return; | 487 return; |
| 486 c->translate(tx, ty); | 488 c->translate(tx, ty); |
| 487 m_path.transform(AffineTransform().translate(-tx, -ty)); | 489 m_path.transform(AffineTransform().translate(-tx, -ty)); |
| 488 } | 490 } |
| 489 | 491 |
| 490 void BaseRenderingContext2D::transform(double m11, | 492 void BaseRenderingContext2D::transform(double m11, |
| 491 double m12, | 493 double m12, |
| 492 double m21, | 494 double m21, |
| 493 double m22, | 495 double m22, |
| 494 double dx, | 496 double dx, |
| 495 double dy) { | 497 double dy) { |
| 496 SkCanvas* c = drawingCanvas(); | 498 CdlCanvas* c = drawingCanvas(); |
| 497 if (!c) | 499 if (!c) |
| 498 return; | 500 return; |
| 499 | 501 |
| 500 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || | 502 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || |
| 501 !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) | 503 !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) |
| 502 return; | 504 return; |
| 503 | 505 |
| 504 AffineTransform transform(m11, m12, m21, m22, dx, dy); | 506 AffineTransform transform(m11, m12, m21, m22, dx, dy); |
| 505 AffineTransform newTransform = state().transform() * transform; | 507 AffineTransform newTransform = state().transform() * transform; |
| 506 if (state().transform() == newTransform) | 508 if (state().transform() == newTransform) |
| 507 return; | 509 return; |
| 508 | 510 |
| 509 modifiableState().setTransform(newTransform); | 511 modifiableState().setTransform(newTransform); |
| 510 if (!state().isTransformInvertible()) | 512 if (!state().isTransformInvertible()) |
| 511 return; | 513 return; |
| 512 | 514 |
| 513 c->concat(affineTransformToSkMatrix(transform)); | 515 c->concat(affineTransformToSkMatrix(transform)); |
| 514 m_path.transform(transform.inverse()); | 516 m_path.transform(transform.inverse()); |
| 515 } | 517 } |
| 516 | 518 |
| 517 void BaseRenderingContext2D::resetTransform() { | 519 void BaseRenderingContext2D::resetTransform() { |
| 518 SkCanvas* c = drawingCanvas(); | 520 CdlCanvas* c = drawingCanvas(); |
| 519 if (!c) | 521 if (!c) |
| 520 return; | 522 return; |
| 521 | 523 |
| 522 AffineTransform ctm = state().transform(); | 524 AffineTransform ctm = state().transform(); |
| 523 bool invertibleCTM = state().isTransformInvertible(); | 525 bool invertibleCTM = state().isTransformInvertible(); |
| 524 // It is possible that CTM is identity while CTM is not invertible. | 526 // It is possible that CTM is identity while CTM is not invertible. |
| 525 // When CTM becomes non-invertible, realizeSaves() can make CTM identity. | 527 // When CTM becomes non-invertible, realizeSaves() can make CTM identity. |
| 526 if (ctm.isIdentity() && invertibleCTM) | 528 if (ctm.isIdentity() && invertibleCTM) |
| 527 return; | 529 return; |
| 528 | 530 |
| 529 // resetTransform() resolves the non-invertible CTM state. | 531 // resetTransform() resolves the non-invertible CTM state. |
| 530 modifiableState().resetTransform(); | 532 modifiableState().resetTransform(); |
| 531 c->setMatrix(affineTransformToSkMatrix(baseTransform())); | 533 c->setMatrix(affineTransformToSkMatrix(baseTransform())); |
| 532 | 534 |
| 533 if (invertibleCTM) | 535 if (invertibleCTM) |
| 534 m_path.transform(ctm); | 536 m_path.transform(ctm); |
| 535 // When else, do nothing because all transform methods didn't update m_path | 537 // When else, do nothing because all transform methods didn't update m_path |
| 536 // when CTM became non-invertible. | 538 // when CTM became non-invertible. |
| 537 // It means that resetTransform() restores m_path just before CTM became | 539 // It means that resetTransform() restores m_path just before CTM became |
| 538 // non-invertible. | 540 // non-invertible. |
| 539 } | 541 } |
| 540 | 542 |
| 541 void BaseRenderingContext2D::setTransform(double m11, | 543 void BaseRenderingContext2D::setTransform(double m11, |
| 542 double m12, | 544 double m12, |
| 543 double m21, | 545 double m21, |
| 544 double m22, | 546 double m22, |
| 545 double dx, | 547 double dx, |
| 546 double dy) { | 548 double dy) { |
| 547 SkCanvas* c = drawingCanvas(); | 549 CdlCanvas* c = drawingCanvas(); |
| 548 if (!c) | 550 if (!c) |
| 549 return; | 551 return; |
| 550 | 552 |
| 551 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || | 553 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || |
| 552 !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) | 554 !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) |
| 553 return; | 555 return; |
| 554 | 556 |
| 555 resetTransform(); | 557 resetTransform(); |
| 556 transform(m11, m12, m21, m22, dx, dy); | 558 transform(m11, m12, m21, m22, dx, dy); |
| 557 } | 559 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 SkPath skPath = path.getSkPath(); | 617 SkPath skPath = path.getSkPath(); |
| 616 FloatRect bounds = path.boundingRect(); | 618 FloatRect bounds = path.boundingRect(); |
| 617 skPath.setFillType(fillType); | 619 skPath.setFillType(fillType); |
| 618 | 620 |
| 619 if (paintType == CanvasRenderingContext2DState::StrokePaintType) | 621 if (paintType == CanvasRenderingContext2DState::StrokePaintType) |
| 620 inflateStrokeRect(bounds); | 622 inflateStrokeRect(bounds); |
| 621 | 623 |
| 622 if (!drawingCanvas()) | 624 if (!drawingCanvas()) |
| 623 return; | 625 return; |
| 624 | 626 |
| 625 if (draw([&skPath, this](SkCanvas* c, const SkPaint* paint) // draw lambda | 627 if (draw([&skPath, this](CdlCanvas* c, const CdlPaint* paint) // draw lambda |
| 626 { c->drawPath(skPath, *paint); }, | 628 { c->drawPath(skPath, *paint); }, |
| 627 [](const SkIRect& rect) // overdraw test lambda | 629 [](const SkIRect& rect) // overdraw test lambda |
| 628 { return false; }, | 630 { return false; }, |
| 629 bounds, paintType)) { | 631 bounds, paintType)) { |
| 630 if (isPathExpensive(path)) { | 632 if (isPathExpensive(path)) { |
| 631 ImageBuffer* buffer = imageBuffer(); | 633 ImageBuffer* buffer = imageBuffer(); |
| 632 if (buffer) | 634 if (buffer) |
| 633 buffer->setHasExpensiveOp(); | 635 buffer->setHasExpensiveOp(); |
| 634 } | 636 } |
| 635 } | 637 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 double width, | 677 double width, |
| 676 double height) { | 678 double height) { |
| 677 trackDrawCall(FillRect, nullptr, width, height); | 679 trackDrawCall(FillRect, nullptr, width, height); |
| 678 if (!validateRectForCanvas(x, y, width, height)) | 680 if (!validateRectForCanvas(x, y, width, height)) |
| 679 return; | 681 return; |
| 680 | 682 |
| 681 if (!drawingCanvas()) | 683 if (!drawingCanvas()) |
| 682 return; | 684 return; |
| 683 | 685 |
| 684 SkRect rect = SkRect::MakeXYWH(x, y, width, height); | 686 SkRect rect = SkRect::MakeXYWH(x, y, width, height); |
| 685 draw([&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda | 687 draw([&rect, this](CdlCanvas* c, const CdlPaint* paint) // draw lambda |
| 686 { c->drawRect(rect, *paint); }, | 688 { c->drawRect(rect, *paint); }, |
| 687 [&rect, this](const SkIRect& clipBounds) // overdraw test lambda | 689 [&rect, this](const SkIRect& clipBounds) // overdraw test lambda |
| 688 { return rectContainsTransformedRect(rect, clipBounds); }, | 690 { return rectContainsTransformedRect(rect, clipBounds); }, |
| 689 rect, CanvasRenderingContext2DState::FillPaintType); | 691 rect, CanvasRenderingContext2DState::FillPaintType); |
| 690 } | 692 } |
| 691 | 693 |
| 692 static void strokeRectOnCanvas(const FloatRect& rect, | 694 static void strokeRectOnCanvas(const FloatRect& rect, |
| 693 SkCanvas* canvas, | 695 CdlCanvas* canvas, |
| 694 const SkPaint* paint) { | 696 const CdlPaint* paint) { |
| 695 ASSERT(paint->getStyle() == SkPaint::kStroke_Style); | 697 ASSERT(paint->getStyle() == SkPaint::kStroke_Style); |
| 696 if ((rect.width() > 0) != (rect.height() > 0)) { | 698 if ((rect.width() > 0) != (rect.height() > 0)) { |
| 697 // When stroking, we must skip the zero-dimension segments | 699 // When stroking, we must skip the zero-dimension segments |
| 698 SkPath path; | 700 SkPath path; |
| 699 path.moveTo(rect.x(), rect.y()); | 701 path.moveTo(rect.x(), rect.y()); |
| 700 path.lineTo(rect.maxX(), rect.maxY()); | 702 path.lineTo(rect.maxX(), rect.maxY()); |
| 701 path.close(); | 703 path.close(); |
| 702 canvas->drawPath(path, *paint); | 704 canvas->drawPath(path, *paint); |
| 703 return; | 705 return; |
| 704 } | 706 } |
| 705 canvas->drawRect(rect, *paint); | 707 canvas->drawRect(rect, *paint); |
| 706 } | 708 } |
| 707 | 709 |
| 708 void BaseRenderingContext2D::strokeRect(double x, | 710 void BaseRenderingContext2D::strokeRect(double x, |
| 709 double y, | 711 double y, |
| 710 double width, | 712 double width, |
| 711 double height) { | 713 double height) { |
| 712 trackDrawCall(StrokeRect, nullptr, width, height); | 714 trackDrawCall(StrokeRect, nullptr, width, height); |
| 713 if (!validateRectForCanvas(x, y, width, height)) | 715 if (!validateRectForCanvas(x, y, width, height)) |
| 714 return; | 716 return; |
| 715 | 717 |
| 716 if (!drawingCanvas()) | 718 if (!drawingCanvas()) |
| 717 return; | 719 return; |
| 718 | 720 |
| 719 SkRect rect = SkRect::MakeXYWH(x, y, width, height); | 721 SkRect rect = SkRect::MakeXYWH(x, y, width, height); |
| 720 FloatRect bounds = rect; | 722 FloatRect bounds = rect; |
| 721 inflateStrokeRect(bounds); | 723 inflateStrokeRect(bounds); |
| 722 draw([&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda | 724 draw([&rect, this](CdlCanvas* c, const CdlPaint* paint) // draw lambda |
| 723 { strokeRectOnCanvas(rect, c, paint); }, | 725 { strokeRectOnCanvas(rect, c, paint); }, |
| 724 [](const SkIRect& clipBounds) // overdraw test lambda | 726 [](const SkIRect& clipBounds) // overdraw test lambda |
| 725 { return false; }, | 727 { return false; }, |
| 726 bounds, CanvasRenderingContext2DState::StrokePaintType); | 728 bounds, CanvasRenderingContext2DState::StrokePaintType); |
| 727 } | 729 } |
| 728 | 730 |
| 729 void BaseRenderingContext2D::clipInternal(const Path& path, | 731 void BaseRenderingContext2D::clipInternal(const Path& path, |
| 730 const String& windingRuleString) { | 732 const String& windingRuleString) { |
| 731 SkCanvas* c = drawingCanvas(); | 733 CdlCanvas* c = drawingCanvas(); |
| 732 if (!c) { | 734 if (!c) { |
| 733 return; | 735 return; |
| 734 } | 736 } |
| 735 if (!state().isTransformInvertible()) { | 737 if (!state().isTransformInvertible()) { |
| 736 return; | 738 return; |
| 737 } | 739 } |
| 738 | 740 |
| 739 SkPath skPath = path.getSkPath(); | 741 SkPath skPath = path.getSkPath(); |
| 740 skPath.setFillType(parseWinding(windingRuleString)); | 742 skPath.setFillType(parseWinding(windingRuleString)); |
| 741 modifiableState().clipPath(skPath, m_clipAntialiasing); | 743 modifiableState().clipPath(skPath, m_clipAntialiasing); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 767 const double y, | 769 const double y, |
| 768 const String& windingRuleString) { | 770 const String& windingRuleString) { |
| 769 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); | 771 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); |
| 770 } | 772 } |
| 771 | 773 |
| 772 bool BaseRenderingContext2D::isPointInPathInternal( | 774 bool BaseRenderingContext2D::isPointInPathInternal( |
| 773 const Path& path, | 775 const Path& path, |
| 774 const double x, | 776 const double x, |
| 775 const double y, | 777 const double y, |
| 776 const String& windingRuleString) { | 778 const String& windingRuleString) { |
| 777 SkCanvas* c = drawingCanvas(); | 779 CdlCanvas* c = drawingCanvas(); |
| 778 if (!c) | 780 if (!c) |
| 779 return false; | 781 return false; |
| 780 if (!state().isTransformInvertible()) | 782 if (!state().isTransformInvertible()) |
| 781 return false; | 783 return false; |
| 782 | 784 |
| 783 FloatPoint point(x, y); | 785 FloatPoint point(x, y); |
| 784 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) | 786 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) |
| 785 return false; | 787 return false; |
| 786 AffineTransform ctm = state().transform(); | 788 AffineTransform ctm = state().transform(); |
| 787 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); | 789 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); |
| 788 | 790 |
| 789 return path.contains(transformedPoint, | 791 return path.contains(transformedPoint, |
| 790 SkFillTypeToWindRule(parseWinding(windingRuleString))); | 792 SkFillTypeToWindRule(parseWinding(windingRuleString))); |
| 791 } | 793 } |
| 792 | 794 |
| 793 bool BaseRenderingContext2D::isPointInStroke(const double x, const double y) { | 795 bool BaseRenderingContext2D::isPointInStroke(const double x, const double y) { |
| 794 return isPointInStrokeInternal(m_path, x, y); | 796 return isPointInStrokeInternal(m_path, x, y); |
| 795 } | 797 } |
| 796 | 798 |
| 797 bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath, | 799 bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath, |
| 798 const double x, | 800 const double x, |
| 799 const double y) { | 801 const double y) { |
| 800 return isPointInStrokeInternal(domPath->path(), x, y); | 802 return isPointInStrokeInternal(domPath->path(), x, y); |
| 801 } | 803 } |
| 802 | 804 |
| 803 bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path, | 805 bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path, |
| 804 const double x, | 806 const double x, |
| 805 const double y) { | 807 const double y) { |
| 806 SkCanvas* c = drawingCanvas(); | 808 CdlCanvas* c = drawingCanvas(); |
| 807 if (!c) | 809 if (!c) |
| 808 return false; | 810 return false; |
| 809 if (!state().isTransformInvertible()) | 811 if (!state().isTransformInvertible()) |
| 810 return false; | 812 return false; |
| 811 | 813 |
| 812 FloatPoint point(x, y); | 814 FloatPoint point(x, y); |
| 813 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) | 815 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) |
| 814 return false; | 816 return false; |
| 815 AffineTransform ctm = state().transform(); | 817 AffineTransform ctm = state().transform(); |
| 816 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); | 818 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 829 | 831 |
| 830 void BaseRenderingContext2D::clearRect(double x, | 832 void BaseRenderingContext2D::clearRect(double x, |
| 831 double y, | 833 double y, |
| 832 double width, | 834 double width, |
| 833 double height) { | 835 double height) { |
| 834 m_usageCounters.numClearRectCalls++; | 836 m_usageCounters.numClearRectCalls++; |
| 835 | 837 |
| 836 if (!validateRectForCanvas(x, y, width, height)) | 838 if (!validateRectForCanvas(x, y, width, height)) |
| 837 return; | 839 return; |
| 838 | 840 |
| 839 SkCanvas* c = drawingCanvas(); | 841 CdlCanvas* c = drawingCanvas(); |
| 840 if (!c) | 842 if (!c) |
| 841 return; | 843 return; |
| 842 if (!state().isTransformInvertible()) | 844 if (!state().isTransformInvertible()) |
| 843 return; | 845 return; |
| 844 | 846 |
| 845 SkIRect clipBounds; | 847 SkIRect clipBounds; |
| 846 if (!c->getClipDeviceBounds(&clipBounds)) | 848 if (!c->getClipDeviceBounds(&clipBounds)) |
| 847 return; | 849 return; |
| 848 | 850 |
| 849 SkPaint clearPaint; | 851 CdlPaint clearPaint; |
| 850 clearPaint.setBlendMode(SkBlendMode::kClear); | 852 clearPaint.setBlendMode(SkBlendMode::kClear); |
| 851 clearPaint.setStyle(SkPaint::kFill_Style); | 853 clearPaint.setStyle(CdlPaint::kFill_Style); |
| 852 FloatRect rect(x, y, width, height); | 854 FloatRect rect(x, y, width, height); |
| 853 | 855 |
| 854 if (rectContainsTransformedRect(rect, clipBounds)) { | 856 if (rectContainsTransformedRect(rect, clipBounds)) { |
| 855 checkOverdraw(rect, &clearPaint, CanvasRenderingContext2DState::NoImage, | 857 checkOverdraw(rect, &clearPaint, CanvasRenderingContext2DState::NoImage, |
| 856 ClipFill); | 858 ClipFill); |
| 857 if (drawingCanvas()) | 859 if (drawingCanvas()) |
| 858 drawingCanvas()->drawRect(rect, clearPaint); | 860 drawingCanvas()->drawRect(rect, clearPaint); |
| 859 didDraw(clipBounds); | 861 didDraw(clipBounds); |
| 860 } else { | 862 } else { |
| 861 SkIRect dirtyRect; | 863 SkIRect dirtyRect; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 if (!imageSourceInternal) | 992 if (!imageSourceInternal) |
| 991 return; | 993 return; |
| 992 drawImage(executionContext, imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, | 994 drawImage(executionContext, imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, |
| 993 dh, exceptionState); | 995 dh, exceptionState); |
| 994 } | 996 } |
| 995 | 997 |
| 996 bool BaseRenderingContext2D::shouldDrawImageAntialiased( | 998 bool BaseRenderingContext2D::shouldDrawImageAntialiased( |
| 997 const FloatRect& destRect) const { | 999 const FloatRect& destRect) const { |
| 998 if (!state().shouldAntialias()) | 1000 if (!state().shouldAntialias()) |
| 999 return false; | 1001 return false; |
| 1000 SkCanvas* c = drawingCanvas(); | 1002 CdlCanvas* c = drawingCanvas(); |
| 1001 ASSERT(c); | 1003 ASSERT(c); |
| 1002 | 1004 |
| 1003 const SkMatrix& ctm = c->getTotalMatrix(); | 1005 const SkMatrix& ctm = c->getTotalMatrix(); |
| 1004 // Don't disable anti-aliasing if we're rotated or skewed. | 1006 // Don't disable anti-aliasing if we're rotated or skewed. |
| 1005 if (!ctm.rectStaysRect()) | 1007 if (!ctm.rectStaysRect()) |
| 1006 return true; | 1008 return true; |
| 1007 // Check if the dimensions of the destination are "small" (less than one | 1009 // Check if the dimensions of the destination are "small" (less than one |
| 1008 // device pixel). To prevent sudden drop-outs. Since we know that | 1010 // device pixel). To prevent sudden drop-outs. Since we know that |
| 1009 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or | 1011 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or |
| 1010 // vice versa. We can query the kAffine_Mask flag to determine which case | 1012 // vice versa. We can query the kAffine_Mask flag to determine which case |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1026 static bool isDrawScalingDown(const FloatRect& srcRect, | 1028 static bool isDrawScalingDown(const FloatRect& srcRect, |
| 1027 const FloatRect& dstRect, | 1029 const FloatRect& dstRect, |
| 1028 float xScaleSquared, | 1030 float xScaleSquared, |
| 1029 float yScaleSquared) { | 1031 float yScaleSquared) { |
| 1030 return dstRect.width() * dstRect.width() * xScaleSquared < | 1032 return dstRect.width() * dstRect.width() * xScaleSquared < |
| 1031 srcRect.width() * srcRect.width() && | 1033 srcRect.width() * srcRect.width() && |
| 1032 dstRect.height() * dstRect.height() * yScaleSquared < | 1034 dstRect.height() * dstRect.height() * yScaleSquared < |
| 1033 srcRect.height() * srcRect.height(); | 1035 srcRect.height() * srcRect.height(); |
| 1034 } | 1036 } |
| 1035 | 1037 |
| 1036 void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, | 1038 void BaseRenderingContext2D::drawImageInternal(CdlCanvas* c, |
| 1037 CanvasImageSource* imageSource, | 1039 CanvasImageSource* imageSource, |
| 1038 Image* image, | 1040 Image* image, |
| 1039 const FloatRect& srcRect, | 1041 const FloatRect& srcRect, |
| 1040 const FloatRect& dstRect, | 1042 const FloatRect& dstRect, |
| 1041 const SkPaint* paint) { | 1043 const CdlPaint* paint) { |
| 1042 if (imageSource->isSVGSource()) { | 1044 if (imageSource->isSVGSource()) { |
| 1043 trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height()); | 1045 trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height()); |
| 1044 } else { | 1046 } else { |
| 1045 trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height()); | 1047 trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height()); |
| 1046 } | 1048 } |
| 1047 | 1049 |
| 1048 int initialSaveCount = c->getSaveCount(); | 1050 int initialSaveCount = c->getSaveCount(); |
| 1049 SkPaint imagePaint = *paint; | 1051 CdlPaint imagePaint = *paint; |
| 1050 | 1052 |
| 1051 if (paint->getImageFilter()) { | 1053 if (paint->getImageFilter()) { |
| 1052 SkMatrix ctm = c->getTotalMatrix(); | 1054 SkMatrix ctm = c->getTotalMatrix(); |
| 1053 SkMatrix invCtm; | 1055 SkMatrix invCtm; |
| 1054 if (!ctm.invert(&invCtm)) { | 1056 if (!ctm.invert(&invCtm)) { |
| 1055 // There is an earlier check for invertibility, but the arithmetic | 1057 // There is an earlier check for invertibility, but the arithmetic |
| 1056 // in AffineTransform is not exactly identical, so it is possible | 1058 // in AffineTransform is not exactly identical, so it is possible |
| 1057 // for SkMatrix to find the transform to be non-invertible at this stage. | 1059 // for SkMatrix to find the transform to be non-invertible at this stage. |
| 1058 // crbug.com/504687 | 1060 // crbug.com/504687 |
| 1059 return; | 1061 return; |
| 1060 } | 1062 } |
| 1061 c->save(); | 1063 c->save(); |
| 1062 c->concat(invCtm); | 1064 c->concat(invCtm); |
| 1063 SkRect bounds = dstRect; | 1065 SkRect bounds = dstRect; |
| 1064 ctm.mapRect(&bounds); | 1066 ctm.mapRect(&bounds); |
| 1065 SkPaint layerPaint; | 1067 CdlPaint layerPaint; |
| 1066 layerPaint.setBlendMode(paint->getBlendMode()); | 1068 layerPaint.setBlendMode(paint->getBlendMode()); |
| 1067 layerPaint.setImageFilter(sk_ref_sp(paint->getImageFilter())); | 1069 layerPaint.setImageFilter(sk_ref_sp(paint->getImageFilter())); |
| 1068 | 1070 |
| 1069 c->saveLayer(&bounds, &layerPaint); | 1071 c->saveLayer(&bounds, &layerPaint); |
| 1070 c->concat(ctm); | 1072 c->concat(ctm); |
| 1071 imagePaint.setBlendMode(SkBlendMode::kSrcOver); | 1073 imagePaint.setBlendMode(SkBlendMode::kSrcOver); |
| 1072 imagePaint.setImageFilter(nullptr); | 1074 imagePaint.setImageFilter(nullptr); |
| 1073 } | 1075 } |
| 1074 | 1076 |
| 1075 if (!imageSmoothingEnabled() && | 1077 if (!imageSmoothingEnabled() && |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1299 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1298 CustomCountHistogram, scopedUsCounterOthersCPU, | 1300 CustomCountHistogram, scopedUsCounterOthersCPU, |
| 1299 new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0, | 1301 new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0, |
| 1300 10000000, 50)); | 1302 10000000, 50)); |
| 1301 timer.emplace(scopedUsCounterOthersCPU); | 1303 timer.emplace(scopedUsCounterOthersCPU); |
| 1302 } | 1304 } |
| 1303 } | 1305 } |
| 1304 | 1306 |
| 1305 draw( | 1307 draw( |
| 1306 [this, &imageSource, &image, &srcRect, dstRect]( | 1308 [this, &imageSource, &image, &srcRect, dstRect]( |
| 1307 SkCanvas* c, const SkPaint* paint) // draw lambda | 1309 CdlCanvas* c, const CdlPaint* paint) // draw lambda |
| 1308 { | 1310 { |
| 1309 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, paint); | 1311 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, paint); |
| 1310 }, | 1312 }, |
| 1311 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda | 1313 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda |
| 1312 { return rectContainsTransformedRect(dstRect, clipBounds); }, | 1314 { return rectContainsTransformedRect(dstRect, clipBounds); }, |
| 1313 dstRect, CanvasRenderingContext2DState::ImagePaintType, | 1315 dstRect, CanvasRenderingContext2DState::ImagePaintType, |
| 1314 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage | 1316 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage |
| 1315 : CanvasRenderingContext2DState::NonOpaqueImage); | 1317 : CanvasRenderingContext2DState::NonOpaqueImage); |
| 1316 | 1318 |
| 1317 validateStateStack(); | 1319 validateStateStack(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1334 } | 1336 } |
| 1335 | 1337 |
| 1336 if (originClean() && wouldTaintOrigin(imageSource, executionContext)) | 1338 if (originClean() && wouldTaintOrigin(imageSource, executionContext)) |
| 1337 setOriginTainted(); | 1339 setOriginTainted(); |
| 1338 } | 1340 } |
| 1339 | 1341 |
| 1340 void BaseRenderingContext2D::clearCanvas() { | 1342 void BaseRenderingContext2D::clearCanvas() { |
| 1341 FloatRect canvasRect(0, 0, width(), height()); | 1343 FloatRect canvasRect(0, 0, width(), height()); |
| 1342 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, | 1344 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, |
| 1343 ClipFill); | 1345 ClipFill); |
| 1344 SkCanvas* c = drawingCanvas(); | 1346 CdlCanvas* c = drawingCanvas(); |
| 1345 if (c) | 1347 if (c) |
| 1346 c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK); | 1348 c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK); |
| 1347 } | 1349 } |
| 1348 | 1350 |
| 1349 bool BaseRenderingContext2D::rectContainsTransformedRect( | 1351 bool BaseRenderingContext2D::rectContainsTransformedRect( |
| 1350 const FloatRect& rect, | 1352 const FloatRect& rect, |
| 1351 const SkIRect& transformedRect) const { | 1353 const SkIRect& transformedRect) const { |
| 1352 FloatQuad quad(rect); | 1354 FloatQuad quad(rect); |
| 1353 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(), | 1355 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(), |
| 1354 transformedRect.width(), | 1356 transformedRect.width(), |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 | 1712 |
| 1711 void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality) { | 1713 void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality) { |
| 1712 if (quality == state().imageSmoothingQuality()) | 1714 if (quality == state().imageSmoothingQuality()) |
| 1713 return; | 1715 return; |
| 1714 | 1716 |
| 1715 modifiableState().setImageSmoothingQuality(quality); | 1717 modifiableState().setImageSmoothingQuality(quality); |
| 1716 } | 1718 } |
| 1717 | 1719 |
| 1718 void BaseRenderingContext2D::checkOverdraw( | 1720 void BaseRenderingContext2D::checkOverdraw( |
| 1719 const SkRect& rect, | 1721 const SkRect& rect, |
| 1720 const SkPaint* paint, | 1722 const CdlPaint* paint, |
| 1721 CanvasRenderingContext2DState::ImageType imageType, | 1723 CanvasRenderingContext2DState::ImageType imageType, |
| 1722 DrawType drawType) { | 1724 DrawType drawType) { |
| 1723 SkCanvas* c = drawingCanvas(); | 1725 CdlCanvas* c = drawingCanvas(); |
| 1724 if (!c || !imageBuffer()->isRecording()) | 1726 if (!c || !imageBuffer()->isRecording()) |
| 1725 return; | 1727 return; |
| 1726 | 1728 |
| 1727 SkRect deviceRect; | 1729 SkRect deviceRect; |
| 1728 if (drawType == UntransformedUnclippedFill) { | 1730 if (drawType == UntransformedUnclippedFill) { |
| 1729 deviceRect = rect; | 1731 deviceRect = rect; |
| 1730 } else { | 1732 } else { |
| 1731 ASSERT(drawType == ClipFill); | 1733 ASSERT(drawType == ClipFill); |
| 1732 if (state().hasComplexClip()) | 1734 if (state().hasComplexClip()) |
| 1733 return; | 1735 return; |
| 1734 | 1736 |
| 1735 SkIRect skIBounds; | 1737 SkIRect skIBounds; |
| 1736 if (!c->getClipDeviceBounds(&skIBounds)) | 1738 if (!c->getClipDeviceBounds(&skIBounds)) |
| 1737 return; | 1739 return; |
| 1738 deviceRect = SkRect::Make(skIBounds); | 1740 deviceRect = SkRect::Make(skIBounds); |
| 1739 } | 1741 } |
| 1740 | 1742 |
| 1741 const SkImageInfo& imageInfo = c->imageInfo(); | 1743 const SkImageInfo& imageInfo = GetSkCanvas(c)->imageInfo(); |
| 1742 if (!deviceRect.contains( | 1744 if (!deviceRect.contains( |
| 1743 SkRect::MakeWH(imageInfo.width(), imageInfo.height()))) | 1745 SkRect::MakeWH(imageInfo.width(), imageInfo.height()))) |
| 1744 return; | 1746 return; |
| 1745 | 1747 |
| 1746 bool isSourceOver = true; | 1748 bool isSourceOver = true; |
| 1747 unsigned alpha = 0xFF; | 1749 unsigned alpha = 0xFF; |
| 1748 if (paint) { | 1750 if (paint) { |
| 1749 if (paint->getLooper() || paint->getImageFilter() || paint->getMaskFilter()) | 1751 if (paint->getLooper() || paint->getImageFilter() || paint->getMaskFilter()) |
| 1750 return; | 1752 return; |
| 1751 | 1753 |
| 1752 SkBlendMode mode = paint->getBlendMode(); | 1754 SkBlendMode mode = paint->getBlendMode(); |
| 1753 isSourceOver = mode == SkBlendMode::kSrcOver; | 1755 isSourceOver = mode == SkBlendMode::kSrcOver; |
| 1754 if (!isSourceOver && mode != SkBlendMode::kSrc && | 1756 if (!isSourceOver && mode != SkBlendMode::kSrc && |
| 1755 mode != SkBlendMode::kClear) | 1757 mode != SkBlendMode::kClear) |
| 1756 return; // The code below only knows how to handle Src, SrcOver, and | 1758 return; // The code below only knows how to handle Src, SrcOver, and |
| 1757 // Clear | 1759 // Clear |
| 1758 | 1760 |
| 1759 alpha = paint->getAlpha(); | 1761 alpha = paint->getAlpha(); |
| 1760 | 1762 |
| 1761 if (isSourceOver && imageType == CanvasRenderingContext2DState::NoImage) { | 1763 if (isSourceOver && imageType == CanvasRenderingContext2DState::NoImage) { |
| 1762 SkShader* shader = paint->getShader(); | 1764 CdlShader* shader = paint->getShader(); |
| 1763 if (shader) { | 1765 if (shader) { |
| 1764 if (shader->isOpaque() && alpha == 0xFF) | 1766 if (shader->isOpaque() && alpha == 0xFF) |
| 1765 imageBuffer()->willOverwriteCanvas(); | 1767 imageBuffer()->willOverwriteCanvas(); |
| 1766 return; | 1768 return; |
| 1767 } | 1769 } |
| 1768 } | 1770 } |
| 1769 } | 1771 } |
| 1770 | 1772 |
| 1771 if (isSourceOver) { | 1773 if (isSourceOver) { |
| 1772 // With source over, we need to certify that alpha == 0xFF for all pixels | 1774 // With source over, we need to certify that alpha == 0xFF for all pixels |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * | 2016 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * |
| 2015 m_usageCounters.numBlurredShadows + | 2017 m_usageCounters.numBlurredShadows + |
| 2016 ExpensiveCanvasHeuristicParameters:: | 2018 ExpensiveCanvasHeuristicParameters:: |
| 2017 ShadowVariableCostPerAreaTimesShadowBlurSquared[index] * | 2019 ShadowVariableCostPerAreaTimesShadowBlurSquared[index] * |
| 2018 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared; | 2020 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared; |
| 2019 | 2021 |
| 2020 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment; | 2022 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment; |
| 2021 } | 2023 } |
| 2022 | 2024 |
| 2023 } // namespace blink | 2025 } // namespace blink |
| OLD | NEW |