Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp

Issue 2523673004: [NOT FOR COMMIT] Fully replace SkCanvas uses.
Patch Set: Support Android build. Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698