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

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

Issue 2640983002: Rename paint data structures (Closed)
Patch Set: DrawingDisplayItem Created 3 years, 10 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 "core/css/cssom/CSSURLImageValue.h" 9 #include "core/css/cssom/CSSURLImageValue.h"
10 #include "core/css/parser/CSSParser.h" 10 #include "core/css/parser/CSSParser.h"
11 #include "core/frame/ImageBitmap.h" 11 #include "core/frame/ImageBitmap.h"
12 #include "core/html/HTMLCanvasElement.h" 12 #include "core/html/HTMLCanvasElement.h"
13 #include "core/html/HTMLImageElement.h" 13 #include "core/html/HTMLImageElement.h"
14 #include "core/html/HTMLVideoElement.h" 14 #include "core/html/HTMLVideoElement.h"
15 #include "core/html/ImageData.h" 15 #include "core/html/ImageData.h"
16 #include "core/offscreencanvas/OffscreenCanvas.h" 16 #include "core/offscreencanvas/OffscreenCanvas.h"
17 #include "modules/canvas2d/CanvasGradient.h" 17 #include "modules/canvas2d/CanvasGradient.h"
18 #include "modules/canvas2d/CanvasPattern.h" 18 #include "modules/canvas2d/CanvasPattern.h"
19 #include "modules/canvas2d/CanvasStyle.h" 19 #include "modules/canvas2d/CanvasStyle.h"
20 #include "modules/canvas2d/Path2D.h" 20 #include "modules/canvas2d/Path2D.h"
21 #include "platform/Histogram.h" 21 #include "platform/Histogram.h"
22 #include "platform/RuntimeEnabledFeatures.h" 22 #include "platform/RuntimeEnabledFeatures.h"
23 #include "platform/geometry/FloatQuad.h" 23 #include "platform/geometry/FloatQuad.h"
24 #include "platform/graphics/Color.h" 24 #include "platform/graphics/Color.h"
25 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" 25 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
26 #include "platform/graphics/Image.h" 26 #include "platform/graphics/Image.h"
27 #include "platform/graphics/ImageBuffer.h" 27 #include "platform/graphics/ImageBuffer.h"
28 #include "platform/graphics/StrokeData.h" 28 #include "platform/graphics/StrokeData.h"
29 #include "platform/graphics/paint/PaintCanvas.h"
30 #include "platform/graphics/paint/PaintFlags.h"
29 #include "platform/graphics/skia/SkiaUtils.h" 31 #include "platform/graphics/skia/SkiaUtils.h"
30 32
31 namespace blink { 33 namespace blink {
32 34
33 BaseRenderingContext2D::BaseRenderingContext2D() 35 BaseRenderingContext2D::BaseRenderingContext2D()
34 : m_clipAntialiasing(NotAntiAliased) { 36 : m_clipAntialiasing(NotAntiAliased) {
35 m_stateStack.push_back(CanvasRenderingContext2DState::create()); 37 m_stateStack.push_back(CanvasRenderingContext2DState::create());
36 } 38 }
37 39
38 BaseRenderingContext2D::~BaseRenderingContext2D() {} 40 BaseRenderingContext2D::~BaseRenderingContext2D() {}
(...skipping 12 matching lines...) Expand all
51 m_stateStack.back()->restore(); 53 m_stateStack.back()->restore();
52 m_stateStack.push_back(CanvasRenderingContext2DState::create( 54 m_stateStack.push_back(CanvasRenderingContext2DState::create(
53 state(), CanvasRenderingContext2DState::DontCopyClipList)); 55 state(), CanvasRenderingContext2DState::DontCopyClipList));
54 // Set the new state's unrealized count to 0, because it has no outstanding 56 // Set the new state's unrealized count to 0, because it has no outstanding
55 // saves. 57 // saves.
56 // We need to do this explicitly because the copy constructor and operator= 58 // We need to do this explicitly because the copy constructor and operator=
57 // used by the Vector operations copy the unrealized count from the previous 59 // used by the Vector operations copy the unrealized count from the previous
58 // state (in turn necessary to support correct resizing and unwinding of the 60 // state (in turn necessary to support correct resizing and unwinding of the
59 // stack). 61 // stack).
60 m_stateStack.back()->resetUnrealizedSaveCount(); 62 m_stateStack.back()->resetUnrealizedSaveCount();
61 SkCanvas* canvas = drawingCanvas(); 63 PaintCanvas* canvas = drawingCanvas();
62 if (canvas) 64 if (canvas)
63 canvas->save(); 65 canvas->save();
64 validateStateStack(); 66 validateStateStack();
65 } 67 }
66 } 68 }
67 69
68 void BaseRenderingContext2D::save() { 70 void BaseRenderingContext2D::save() {
69 m_stateStack.back()->save(); 71 m_stateStack.back()->save();
70 } 72 }
71 73
72 void BaseRenderingContext2D::restore() { 74 void BaseRenderingContext2D::restore() {
73 validateStateStack(); 75 validateStateStack();
74 if (state().hasUnrealizedSaves()) { 76 if (state().hasUnrealizedSaves()) {
75 // We never realized the save, so just record that it was unnecessary. 77 // We never realized the save, so just record that it was unnecessary.
76 m_stateStack.back()->restore(); 78 m_stateStack.back()->restore();
77 return; 79 return;
78 } 80 }
79 ASSERT(m_stateStack.size() >= 1); 81 ASSERT(m_stateStack.size() >= 1);
80 if (m_stateStack.size() <= 1) 82 if (m_stateStack.size() <= 1)
81 return; 83 return;
82 m_path.transform(state().transform()); 84 m_path.transform(state().transform());
83 m_stateStack.pop_back(); 85 m_stateStack.pop_back();
84 m_stateStack.back()->clearResolvedFilter(); 86 m_stateStack.back()->clearResolvedFilter();
85 m_path.transform(state().transform().inverse()); 87 m_path.transform(state().transform().inverse());
86 SkCanvas* c = drawingCanvas(); 88 PaintCanvas* c = drawingCanvas();
87 if (c) 89 if (c)
88 c->restore(); 90 c->restore();
89 91
90 validateStateStack(); 92 validateStateStack();
91 } 93 }
92 94
93 void BaseRenderingContext2D::restoreMatrixClipStack(SkCanvas* c) const { 95 void BaseRenderingContext2D::restoreMatrixClipStack(PaintCanvas* c) const {
94 if (!c) 96 if (!c)
95 return; 97 return;
96 HeapVector<Member<CanvasRenderingContext2DState>>::const_iterator currState; 98 HeapVector<Member<CanvasRenderingContext2DState>>::const_iterator currState;
97 DCHECK(m_stateStack.begin() < m_stateStack.end()); 99 DCHECK(m_stateStack.begin() < m_stateStack.end());
98 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); 100 for (currState = m_stateStack.begin(); currState < m_stateStack.end();
99 currState++) { 101 currState++) {
100 c->setMatrix(SkMatrix::I()); 102 c->setMatrix(SkMatrix::I());
101 if (currState->get()) { 103 if (currState->get()) {
102 currState->get()->playbackClips(c); 104 currState->get()->playbackClips(c);
103 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform())); 105 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform()));
104 } 106 }
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 (PaintCanvas* 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 (PaintCanvas* 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->getDeviceClipBounds(&clipBounds)); 137 DCHECK(c->getDeviceClipBounds(&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 PaintCanvas* 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 PaintCanvas* 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 PaintCanvas* 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 PaintCanvas* 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 PaintCanvas* 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 PaintCanvas* 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](SkCanvas* c, const SkPaint* paint) // draw lambda 627 if (draw([&skPath](PaintCanvas* c, const PaintFlags* 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](SkCanvas* c, const SkPaint* paint) // draw lambda 687 draw([&rect](PaintCanvas* c, const PaintFlags* 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 PaintCanvas* canvas,
694 const SkPaint* paint) { 696 const PaintFlags* 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](SkCanvas* c, const SkPaint* paint) // draw lambda 724 draw([&rect](PaintCanvas* c, const PaintFlags* 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 PaintCanvas* 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 24 matching lines...) Expand all
766 const double y, 768 const double y,
767 const String& windingRuleString) { 769 const String& windingRuleString) {
768 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); 770 return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
769 } 771 }
770 772
771 bool BaseRenderingContext2D::isPointInPathInternal( 773 bool BaseRenderingContext2D::isPointInPathInternal(
772 const Path& path, 774 const Path& path,
773 const double x, 775 const double x,
774 const double y, 776 const double y,
775 const String& windingRuleString) { 777 const String& windingRuleString) {
776 SkCanvas* c = drawingCanvas(); 778 PaintCanvas* c = drawingCanvas();
777 if (!c) 779 if (!c)
778 return false; 780 return false;
779 if (!state().isTransformInvertible()) 781 if (!state().isTransformInvertible())
780 return false; 782 return false;
781 783
782 FloatPoint point(x, y); 784 FloatPoint point(x, y);
783 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) 785 if (!std::isfinite(point.x()) || !std::isfinite(point.y()))
784 return false; 786 return false;
785 AffineTransform ctm = state().transform(); 787 AffineTransform ctm = state().transform();
786 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); 788 FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
787 789
788 return path.contains(transformedPoint, 790 return path.contains(transformedPoint,
789 SkFillTypeToWindRule(parseWinding(windingRuleString))); 791 SkFillTypeToWindRule(parseWinding(windingRuleString)));
790 } 792 }
791 793
792 bool BaseRenderingContext2D::isPointInStroke(const double x, const double y) { 794 bool BaseRenderingContext2D::isPointInStroke(const double x, const double y) {
793 return isPointInStrokeInternal(m_path, x, y); 795 return isPointInStrokeInternal(m_path, x, y);
794 } 796 }
795 797
796 bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath, 798 bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath,
797 const double x, 799 const double x,
798 const double y) { 800 const double y) {
799 return isPointInStrokeInternal(domPath->path(), x, y); 801 return isPointInStrokeInternal(domPath->path(), x, y);
800 } 802 }
801 803
802 bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path, 804 bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path,
803 const double x, 805 const double x,
804 const double y) { 806 const double y) {
805 SkCanvas* c = drawingCanvas(); 807 PaintCanvas* c = drawingCanvas();
806 if (!c) 808 if (!c)
807 return false; 809 return false;
808 if (!state().isTransformInvertible()) 810 if (!state().isTransformInvertible())
809 return false; 811 return false;
810 812
811 FloatPoint point(x, y); 813 FloatPoint point(x, y);
812 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) 814 if (!std::isfinite(point.x()) || !std::isfinite(point.y()))
813 return false; 815 return false;
814 AffineTransform ctm = state().transform(); 816 AffineTransform ctm = state().transform();
815 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); 817 FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
(...skipping 12 matching lines...) Expand all
828 830
829 void BaseRenderingContext2D::clearRect(double x, 831 void BaseRenderingContext2D::clearRect(double x,
830 double y, 832 double y,
831 double width, 833 double width,
832 double height) { 834 double height) {
833 m_usageCounters.numClearRectCalls++; 835 m_usageCounters.numClearRectCalls++;
834 836
835 if (!validateRectForCanvas(x, y, width, height)) 837 if (!validateRectForCanvas(x, y, width, height))
836 return; 838 return;
837 839
838 SkCanvas* c = drawingCanvas(); 840 PaintCanvas* c = drawingCanvas();
839 if (!c) 841 if (!c)
840 return; 842 return;
841 if (!state().isTransformInvertible()) 843 if (!state().isTransformInvertible())
842 return; 844 return;
843 845
844 SkIRect clipBounds; 846 SkIRect clipBounds;
845 if (!c->getDeviceClipBounds(&clipBounds)) 847 if (!c->getDeviceClipBounds(&clipBounds))
846 return; 848 return;
847 849
848 SkPaint clearPaint; 850 PaintFlags clearPaint;
849 clearPaint.setBlendMode(SkBlendMode::kClear); 851 clearPaint.setBlendMode(SkBlendMode::kClear);
850 clearPaint.setStyle(SkPaint::kFill_Style); 852 clearPaint.setStyle(PaintFlags::kFill_Style);
851 FloatRect rect(x, y, width, height); 853 FloatRect rect(x, y, width, height);
852 854
853 if (rectContainsTransformedRect(rect, clipBounds)) { 855 if (rectContainsTransformedRect(rect, clipBounds)) {
854 checkOverdraw(rect, &clearPaint, CanvasRenderingContext2DState::NoImage, 856 checkOverdraw(rect, &clearPaint, CanvasRenderingContext2DState::NoImage,
855 ClipFill); 857 ClipFill);
856 if (drawingCanvas()) 858 if (drawingCanvas())
857 drawingCanvas()->drawRect(rect, clearPaint); 859 drawingCanvas()->drawRect(rect, clearPaint);
858 didDraw(clipBounds); 860 didDraw(clipBounds);
859 } else { 861 } else {
860 SkIRect dirtyRect; 862 SkIRect dirtyRect;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 if (!imageSourceInternal) 991 if (!imageSourceInternal)
990 return; 992 return;
991 drawImage(executionContext, imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, 993 drawImage(executionContext, imageSourceInternal, sx, sy, sw, sh, dx, dy, dw,
992 dh, exceptionState); 994 dh, exceptionState);
993 } 995 }
994 996
995 bool BaseRenderingContext2D::shouldDrawImageAntialiased( 997 bool BaseRenderingContext2D::shouldDrawImageAntialiased(
996 const FloatRect& destRect) const { 998 const FloatRect& destRect) const {
997 if (!state().shouldAntialias()) 999 if (!state().shouldAntialias())
998 return false; 1000 return false;
999 SkCanvas* c = drawingCanvas(); 1001 PaintCanvas* c = drawingCanvas();
1000 ASSERT(c); 1002 ASSERT(c);
1001 1003
1002 const SkMatrix& ctm = c->getTotalMatrix(); 1004 const SkMatrix& ctm = c->getTotalMatrix();
1003 // Don't disable anti-aliasing if we're rotated or skewed. 1005 // Don't disable anti-aliasing if we're rotated or skewed.
1004 if (!ctm.rectStaysRect()) 1006 if (!ctm.rectStaysRect())
1005 return true; 1007 return true;
1006 // Check if the dimensions of the destination are "small" (less than one 1008 // Check if the dimensions of the destination are "small" (less than one
1007 // device pixel). To prevent sudden drop-outs. Since we know that 1009 // device pixel). To prevent sudden drop-outs. Since we know that
1008 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or 1010 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or
1009 // vice versa. We can query the kAffine_Mask flag to determine which case 1011 // vice versa. We can query the kAffine_Mask flag to determine which case
(...skipping 15 matching lines...) Expand all
1025 static bool isDrawScalingDown(const FloatRect& srcRect, 1027 static bool isDrawScalingDown(const FloatRect& srcRect,
1026 const FloatRect& dstRect, 1028 const FloatRect& dstRect,
1027 float xScaleSquared, 1029 float xScaleSquared,
1028 float yScaleSquared) { 1030 float yScaleSquared) {
1029 return dstRect.width() * dstRect.width() * xScaleSquared < 1031 return dstRect.width() * dstRect.width() * xScaleSquared <
1030 srcRect.width() * srcRect.width() && 1032 srcRect.width() * srcRect.width() &&
1031 dstRect.height() * dstRect.height() * yScaleSquared < 1033 dstRect.height() * dstRect.height() * yScaleSquared <
1032 srcRect.height() * srcRect.height(); 1034 srcRect.height() * srcRect.height();
1033 } 1035 }
1034 1036
1035 void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, 1037 void BaseRenderingContext2D::drawImageInternal(PaintCanvas* c,
1036 CanvasImageSource* imageSource, 1038 CanvasImageSource* imageSource,
1037 Image* image, 1039 Image* image,
1038 const FloatRect& srcRect, 1040 const FloatRect& srcRect,
1039 const FloatRect& dstRect, 1041 const FloatRect& dstRect,
1040 const SkPaint* paint) { 1042 const PaintFlags* paint) {
1041 if (imageSource->isSVGSource()) { 1043 if (imageSource->isSVGSource()) {
1042 trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height()); 1044 trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height());
1043 } else { 1045 } else {
1044 trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height()); 1046 trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height());
1045 } 1047 }
1046 1048
1047 int initialSaveCount = c->getSaveCount(); 1049 int initialSaveCount = c->getSaveCount();
1048 SkPaint imagePaint = *paint; 1050 PaintFlags imagePaint = *paint;
1049 1051
1050 if (paint->getImageFilter()) { 1052 if (paint->getImageFilter()) {
1051 SkMatrix ctm = c->getTotalMatrix(); 1053 SkMatrix ctm = c->getTotalMatrix();
1052 SkMatrix invCtm; 1054 SkMatrix invCtm;
1053 if (!ctm.invert(&invCtm)) { 1055 if (!ctm.invert(&invCtm)) {
1054 // There is an earlier check for invertibility, but the arithmetic 1056 // There is an earlier check for invertibility, but the arithmetic
1055 // in AffineTransform is not exactly identical, so it is possible 1057 // in AffineTransform is not exactly identical, so it is possible
1056 // for SkMatrix to find the transform to be non-invertible at this stage. 1058 // for SkMatrix to find the transform to be non-invertible at this stage.
1057 // crbug.com/504687 1059 // crbug.com/504687
1058 return; 1060 return;
1059 } 1061 }
1060 c->save(); 1062 c->save();
1061 c->concat(invCtm); 1063 c->concat(invCtm);
1062 SkRect bounds = dstRect; 1064 SkRect bounds = dstRect;
1063 ctm.mapRect(&bounds); 1065 ctm.mapRect(&bounds);
1064 SkPaint layerPaint; 1066 PaintFlags layerPaint;
1065 layerPaint.setBlendMode(paint->getBlendMode()); 1067 layerPaint.setBlendMode(paint->getBlendMode());
1066 layerPaint.setImageFilter(paint->refImageFilter()); 1068 layerPaint.setImageFilter(paint->refImageFilter());
1067 1069
1068 c->saveLayer(&bounds, &layerPaint); 1070 c->saveLayer(&bounds, &layerPaint);
1069 c->concat(ctm); 1071 c->concat(ctm);
1070 imagePaint.setBlendMode(SkBlendMode::kSrcOver); 1072 imagePaint.setBlendMode(SkBlendMode::kSrcOver);
1071 imagePaint.setImageFilter(nullptr); 1073 imagePaint.setImageFilter(nullptr);
1072 } 1074 }
1073 1075
1074 if (!imageSmoothingEnabled() && 1076 if (!imageSmoothingEnabled() &&
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 DEFINE_THREAD_SAFE_STATIC_LOCAL( 1302 DEFINE_THREAD_SAFE_STATIC_LOCAL(
1301 CustomCountHistogram, scopedUsCounterOthersCPU, 1303 CustomCountHistogram, scopedUsCounterOthersCPU,
1302 new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0, 1304 new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0,
1303 10000000, 50)); 1305 10000000, 50));
1304 timer.emplace(scopedUsCounterOthersCPU); 1306 timer.emplace(scopedUsCounterOthersCPU);
1305 } 1307 }
1306 } 1308 }
1307 1309
1308 draw( 1310 draw(
1309 [this, &imageSource, &image, &srcRect, dstRect]( 1311 [this, &imageSource, &image, &srcRect, dstRect](
1310 SkCanvas* c, const SkPaint* paint) // draw lambda 1312 PaintCanvas* c, const PaintFlags* paint) // draw lambda
1311 { 1313 {
1312 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, paint); 1314 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, paint);
1313 }, 1315 },
1314 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda 1316 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda
1315 { return rectContainsTransformedRect(dstRect, clipBounds); }, 1317 { return rectContainsTransformedRect(dstRect, clipBounds); },
1316 dstRect, CanvasRenderingContext2DState::ImagePaintType, 1318 dstRect, CanvasRenderingContext2DState::ImagePaintType,
1317 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage 1319 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage
1318 : CanvasRenderingContext2DState::NonOpaqueImage); 1320 : CanvasRenderingContext2DState::NonOpaqueImage);
1319 1321
1320 validateStateStack(); 1322 validateStateStack();
(...skipping 16 matching lines...) Expand all
1337 } 1339 }
1338 1340
1339 if (originClean() && wouldTaintOrigin(imageSource, executionContext)) 1341 if (originClean() && wouldTaintOrigin(imageSource, executionContext))
1340 setOriginTainted(); 1342 setOriginTainted();
1341 } 1343 }
1342 1344
1343 void BaseRenderingContext2D::clearCanvas() { 1345 void BaseRenderingContext2D::clearCanvas() {
1344 FloatRect canvasRect(0, 0, width(), height()); 1346 FloatRect canvasRect(0, 0, width(), height());
1345 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, 1347 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage,
1346 ClipFill); 1348 ClipFill);
1347 SkCanvas* c = drawingCanvas(); 1349 PaintCanvas* c = drawingCanvas();
1348 if (c) 1350 if (c)
1349 c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK); 1351 c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK);
1350 } 1352 }
1351 1353
1352 bool BaseRenderingContext2D::rectContainsTransformedRect( 1354 bool BaseRenderingContext2D::rectContainsTransformedRect(
1353 const FloatRect& rect, 1355 const FloatRect& rect,
1354 const SkIRect& transformedRect) const { 1356 const SkIRect& transformedRect) const {
1355 FloatQuad quad(rect); 1357 FloatQuad quad(rect);
1356 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(), 1358 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(),
1357 transformedRect.width(), 1359 transformedRect.width(),
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 1715
1714 void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality) { 1716 void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality) {
1715 if (quality == state().imageSmoothingQuality()) 1717 if (quality == state().imageSmoothingQuality())
1716 return; 1718 return;
1717 1719
1718 modifiableState().setImageSmoothingQuality(quality); 1720 modifiableState().setImageSmoothingQuality(quality);
1719 } 1721 }
1720 1722
1721 void BaseRenderingContext2D::checkOverdraw( 1723 void BaseRenderingContext2D::checkOverdraw(
1722 const SkRect& rect, 1724 const SkRect& rect,
1723 const SkPaint* paint, 1725 const PaintFlags* paint,
1724 CanvasRenderingContext2DState::ImageType imageType, 1726 CanvasRenderingContext2DState::ImageType imageType,
1725 DrawType drawType) { 1727 DrawType drawType) {
1726 SkCanvas* c = drawingCanvas(); 1728 PaintCanvas* c = drawingCanvas();
1727 if (!c || !imageBuffer()->isRecording()) 1729 if (!c || !imageBuffer()->isRecording())
1728 return; 1730 return;
1729 1731
1730 SkRect deviceRect; 1732 SkRect deviceRect;
1731 if (drawType == UntransformedUnclippedFill) { 1733 if (drawType == UntransformedUnclippedFill) {
1732 deviceRect = rect; 1734 deviceRect = rect;
1733 } else { 1735 } else {
1734 ASSERT(drawType == ClipFill); 1736 ASSERT(drawType == ClipFill);
1735 if (state().hasComplexClip()) 1737 if (state().hasComplexClip())
1736 return; 1738 return;
(...skipping 18 matching lines...) Expand all
1755 SkBlendMode mode = paint->getBlendMode(); 1757 SkBlendMode mode = paint->getBlendMode();
1756 isSourceOver = mode == SkBlendMode::kSrcOver; 1758 isSourceOver = mode == SkBlendMode::kSrcOver;
1757 if (!isSourceOver && mode != SkBlendMode::kSrc && 1759 if (!isSourceOver && mode != SkBlendMode::kSrc &&
1758 mode != SkBlendMode::kClear) 1760 mode != SkBlendMode::kClear)
1759 return; // The code below only knows how to handle Src, SrcOver, and 1761 return; // The code below only knows how to handle Src, SrcOver, and
1760 // Clear 1762 // Clear
1761 1763
1762 alpha = paint->getAlpha(); 1764 alpha = paint->getAlpha();
1763 1765
1764 if (isSourceOver && imageType == CanvasRenderingContext2DState::NoImage) { 1766 if (isSourceOver && imageType == CanvasRenderingContext2DState::NoImage) {
1765 SkShader* shader = paint->getShader(); 1767 PaintShader* shader = paint->getShader();
1766 if (shader) { 1768 if (shader) {
1767 if (shader->isOpaque() && alpha == 0xFF) 1769 if (shader->isOpaque() && alpha == 0xFF)
1768 imageBuffer()->willOverwriteCanvas(); 1770 imageBuffer()->willOverwriteCanvas();
1769 return; 1771 return;
1770 } 1772 }
1771 } 1773 }
1772 } 1774 }
1773 1775
1774 if (isSourceOver) { 1776 if (isSourceOver) {
1775 // With source over, we need to certify that alpha == 0xFF for all pixels 1777 // 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
2017 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * 2019 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] *
2018 m_usageCounters.numBlurredShadows + 2020 m_usageCounters.numBlurredShadows +
2019 ExpensiveCanvasHeuristicParameters:: 2021 ExpensiveCanvasHeuristicParameters::
2020 ShadowVariableCostPerAreaTimesShadowBlurSquared[index] * 2022 ShadowVariableCostPerAreaTimesShadowBlurSquared[index] *
2021 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared; 2023 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared;
2022 2024
2023 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment; 2025 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment;
2024 } 2026 }
2025 2027
2026 } // namespace blink 2028 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698