Chromium Code Reviews| 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/parser/CSSParser.h" | 10 #include "core/css/parser/CSSParser.h" |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 } | 942 } |
| 943 | 943 |
| 944 static bool isDrawScalingDown(const FloatRect& srcRect, const FloatRect& dstRect , float xScaleSquared, float yScaleSquared) | 944 static bool isDrawScalingDown(const FloatRect& srcRect, const FloatRect& dstRect , float xScaleSquared, float yScaleSquared) |
| 945 { | 945 { |
| 946 return dstRect.width() * dstRect.width() * xScaleSquared < srcRect.width() * srcRect.width() | 946 return dstRect.width() * dstRect.width() * xScaleSquared < srcRect.width() * srcRect.width() |
| 947 && dstRect.height() * dstRect.height() * yScaleSquared < srcRect.height( ) * srcRect.height(); | 947 && dstRect.height() * dstRect.height() * yScaleSquared < srcRect.height( ) * srcRect.height(); |
| 948 } | 948 } |
| 949 | 949 |
| 950 void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* i mageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, co nst SkPaint* paint) | 950 void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* i mageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, co nst SkPaint* paint) |
| 951 { | 951 { |
| 952 trackDrawCall(DrawImage, nullptr, dstRect.width(), dstRect.height()); | 952 if (imageSource->isSVGSource()) { |
| 953 trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height( )); | |
| 954 } else { | |
| 955 trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height( )); | |
| 956 } | |
| 957 | |
| 953 | 958 |
| 954 int initialSaveCount = c->getSaveCount(); | 959 int initialSaveCount = c->getSaveCount(); |
| 955 SkPaint imagePaint = *paint; | 960 SkPaint imagePaint = *paint; |
| 956 | 961 |
| 957 if (paint->getImageFilter()) { | 962 if (paint->getImageFilter()) { |
| 958 SkMatrix ctm = c->getTotalMatrix(); | 963 SkMatrix ctm = c->getTotalMatrix(); |
| 959 SkMatrix invCtm; | 964 SkMatrix invCtm; |
| 960 if (!ctm.invert(&invCtm)) { | 965 if (!ctm.invert(&invCtm)) { |
| 961 // There is an earlier check for invertibility, but the arithmetic | 966 // There is an earlier check for invertibility, but the arithmetic |
| 962 // in AffineTransform is not exactly identical, so it is possible | 967 // in AffineTransform is not exactly identical, so it is possible |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1514 // With source over, we need to certify that alpha == 0xFF for all pixel s | 1519 // With source over, we need to certify that alpha == 0xFF for all pixel s |
| 1515 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) | 1520 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) |
| 1516 return; | 1521 return; |
| 1517 if (alpha < 0xFF) | 1522 if (alpha < 0xFF) |
| 1518 return; | 1523 return; |
| 1519 } | 1524 } |
| 1520 | 1525 |
| 1521 imageBuffer()->willOverwriteCanvas(); | 1526 imageBuffer()->willOverwriteCanvas(); |
| 1522 } | 1527 } |
| 1523 | 1528 |
| 1524 void BaseRenderingContext2D::trackDrawCall(DrawCallType callType, Path2D* path2d , int width, int height) | 1529 void BaseRenderingContext2D::trackDrawCall(DrawCallType callType, Path2D* path2d , int width, int height) |
|
Justin Novosad
2016/08/04 17:28:15
To minimize side-effects, could you make this func
sebastienlc
2016/08/04 20:20:17
Done.
| |
| 1525 { | 1530 { |
| 1526 m_usageCounters.numDrawCalls[callType]++; | 1531 m_usageCounters.numDrawCalls[callType]++; |
| 1527 | 1532 |
| 1528 double boundingRectWidth = static_cast<double>(width); | 1533 float boundingRectWidth = static_cast<float>(width); |
| 1529 double boundingRectHeight = static_cast<double>(height); | 1534 float boundingRectHeight = static_cast<float>(height); |
| 1530 double boundingRectArea = boundingRectWidth * boundingRectHeight; | 1535 float boundingRectArea = boundingRectWidth * boundingRectHeight; |
| 1531 double boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRe ctHeight); | 1536 float boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRec tHeight); |
| 1532 | 1537 |
| 1533 if (callType == FillText | 1538 if (callType == FillText |
| 1534 || callType == FillPath | 1539 || callType == FillPath |
| 1535 || callType == StrokeText | 1540 || callType == StrokeText |
| 1536 || callType == StrokePath | 1541 || callType == StrokePath |
| 1537 || callType == FillRect | 1542 || callType == FillRect |
| 1538 || callType == StrokeRect) { | 1543 || callType == StrokeRect) { |
| 1539 | 1544 |
| 1540 SkPath skPath; | 1545 SkPath skPath; |
| 1541 if (path2d) { | 1546 if (path2d) { |
| 1542 skPath = path2d->path().getSkPath(); | 1547 skPath = path2d->path().getSkPath(); |
| 1543 } else { | 1548 } else { |
| 1544 skPath = m_path.getSkPath(); | 1549 skPath = m_path.getSkPath(); |
| 1545 } | 1550 } |
| 1546 | 1551 |
| 1547 if (callType == FillPath && !(skPath.getConvexity() == SkPath::kConvex_C onvexity)) { | 1552 |
| 1548 m_usageCounters.numNonConvexFillPathCalls++; | 1553 if (!(callType == FillRect || callType == StrokeRect || callType == Draw VectorImage || callType == DrawBitmapImage)) { |
| 1554 // The correct width and height were not passed as parameters | |
| 1555 const SkRect& boundingRect = skPath.getBounds(); | |
| 1556 boundingRectWidth = static_cast<float>(std::abs(boundingRect.width() )); | |
| 1557 boundingRectHeight = static_cast<float>(std::abs(boundingRect.height ())); | |
| 1558 boundingRectArea = boundingRectWidth * boundingRectHeight; | |
| 1559 boundingRectPerimeter = 2.0 * boundingRectWidth + 2.0 * boundingRect Height; | |
| 1549 } | 1560 } |
| 1550 | 1561 |
| 1551 if (!(callType == FillRect || callType == StrokeRect || callType == Draw Image)) { | 1562 if (callType == FillPath && skPath.getConvexity() != SkPath::kConvex_Con vexity) { |
| 1552 // The correct width and height were not passed as parameters | 1563 m_usageCounters.numNonConvexFillPathCalls++; |
| 1553 const SkRect& boundingRect = skPath.getBounds(); | 1564 m_usageCounters.nonConvexFillPathArea += boundingRectArea; |
| 1554 boundingRectWidth = static_cast<double>(std::abs(boundingRect.width( ))); | |
| 1555 boundingRectHeight = static_cast<double>(std::abs(boundingRect.heigh t())); | |
| 1556 boundingRectArea = boundingRectWidth * boundingRectHeight; | |
| 1557 boundingRectPerimeter = 2.0 * boundingRectWidth + 2.0 * boundingRect Height; | |
| 1558 } | 1565 } |
| 1559 | 1566 |
| 1560 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter; | 1567 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter; |
| 1561 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; | 1568 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; |
| 1562 | 1569 |
| 1563 CanvasStyle* canvasStyle; | 1570 CanvasStyle* canvasStyle; |
| 1564 if (callType == FillText || callType == FillPath || callType == FillRect ) { | 1571 if (callType == FillText || callType == FillPath || callType == FillRect ) { |
| 1565 canvasStyle = state().fillStyle(); | 1572 canvasStyle = state().fillStyle(); |
| 1566 } else { | 1573 } else { |
| 1567 canvasStyle = state().strokeStyle(); | 1574 canvasStyle = state().strokeStyle(); |
| 1568 } | 1575 } |
| 1569 | 1576 |
| 1570 CanvasGradient* gradient = canvasStyle->getCanvasGradient(); | 1577 CanvasGradient* gradient = canvasStyle->getCanvasGradient(); |
| 1571 if (gradient) { | 1578 if (gradient) { |
| 1572 m_usageCounters.numGradients++; | 1579 |
| 1573 if (gradient->getGradient()->isRadial()) { | 1580 if (gradient->getGradient()->isRadial()) { |
| 1581 m_usageCounters.numRadialGradients++; | |
| 1574 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: RadialGradientFillType] += boundingRectArea; | 1582 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: RadialGradientFillType] += boundingRectArea; |
| 1575 } else { | 1583 } else { |
| 1584 m_usageCounters.numLinearGradients++; | |
| 1576 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: LinearGradientFillType] += boundingRectArea; | 1585 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: LinearGradientFillType] += boundingRectArea; |
| 1577 } | 1586 } |
| 1578 } else if (canvasStyle->getCanvasPattern()) { | 1587 } else if (canvasStyle->getCanvasPattern()) { |
| 1579 m_usageCounters.numPatterns++; | 1588 m_usageCounters.numPatterns++; |
| 1580 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Patt ernFillType] += boundingRectArea; | 1589 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Patt ernFillType] += boundingRectArea; |
| 1581 } else { | 1590 } else { |
| 1582 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Colo rFillType] += boundingRectArea; | 1591 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Colo rFillType] += boundingRectArea; |
| 1583 } | 1592 } |
| 1584 } | 1593 } |
| 1585 | 1594 |
| 1586 if (callType == DrawImage) { | 1595 if (callType == DrawVectorImage || callType == DrawBitmapImage) { |
| 1587 m_usageCounters.boundingBoxPerimeterDrawCalls[DrawImage] += boundingRect Perimeter; | 1596 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter; |
| 1588 m_usageCounters.boundingBoxAreaDrawCalls[DrawImage] += boundingRectArea; | 1597 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; |
| 1589 } | 1598 } |
| 1590 | 1599 |
| 1591 if (callType == FillText | 1600 if (callType == FillText |
| 1592 || callType == FillPath | 1601 || callType == FillPath |
| 1593 || callType == StrokeText | 1602 || callType == StrokeText |
| 1594 || callType == StrokePath | 1603 || callType == StrokePath |
| 1595 || callType == FillRect | 1604 || callType == FillRect |
| 1596 || callType == StrokeRect | 1605 || callType == StrokeRect |
| 1597 || callType == DrawImage) { | 1606 || callType == DrawVectorImage |
| 1607 || callType == DrawBitmapImage) { | |
| 1598 if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0 ) { | 1608 if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0 ) { |
| 1599 m_usageCounters.numBlurredShadows++; | 1609 m_usageCounters.numBlurredShadows++; |
| 1600 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRec tArea * state().shadowBlur() * state().shadowBlur(); | 1610 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRec tArea * state().shadowBlur() * state().shadowBlur(); |
| 1601 m_usageCounters.boundingBoxPerimeterTimesShadowBlurSquared += boundi ngRectPerimeter * state().shadowBlur() * state().shadowBlur(); | 1611 m_usageCounters.boundingBoxPerimeterTimesShadowBlurSquared += boundi ngRectPerimeter * state().shadowBlur() * state().shadowBlur(); |
| 1602 } | 1612 } |
| 1603 } | 1613 } |
| 1604 | 1614 |
| 1605 if (state().hasComplexClip()) { | 1615 if (state().hasComplexClip()) { |
| 1606 m_usageCounters.numDrawWithComplexClips++; | 1616 m_usageCounters.numDrawWithComplexClips++; |
| 1607 } | 1617 } |
| 1608 | 1618 |
| 1609 if (stateHasFilter()) { | 1619 if (stateHasFilter()) { |
| 1610 m_usageCounters.numFilters++; | 1620 m_usageCounters.numFilters++; |
| 1611 } | 1621 } |
| 1612 } | 1622 } |
| 1613 | 1623 |
| 1614 const BaseRenderingContext2D::UsageCounters& BaseRenderingContext2D::getUsage() | 1624 const BaseRenderingContext2D::UsageCounters& BaseRenderingContext2D::getUsage() |
| 1615 { | 1625 { |
| 1616 return m_usageCounters; | 1626 return m_usageCounters; |
| 1617 } | 1627 } |
| 1618 | 1628 |
| 1619 DEFINE_TRACE(BaseRenderingContext2D) | 1629 DEFINE_TRACE(BaseRenderingContext2D) |
| 1620 { | 1630 { |
| 1621 visitor->trace(m_stateStack); | 1631 visitor->trace(m_stateStack); |
| 1622 } | 1632 } |
| 1623 | 1633 |
| 1624 BaseRenderingContext2D::UsageCounters::UsageCounters() : | 1634 BaseRenderingContext2D::UsageCounters::UsageCounters() : |
| 1625 numDrawCalls {0, 0, 0, 0, 0, 0}, | 1635 numDrawCalls {0, 0, 0, 0, 0, 0, 0}, |
| 1626 boundingBoxPerimeterDrawCalls {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, | 1636 boundingBoxPerimeterDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, |
| 1627 boundingBoxAreaDrawCalls {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, | 1637 boundingBoxAreaDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, |
| 1628 boundingBoxAreaFillType {0.0, 0.0, 0.0, 0.0}, | 1638 boundingBoxAreaFillType {0.0f, 0.0f, 0.0f, 0.0f}, |
| 1629 numNonConvexFillPathCalls(0), | 1639 numNonConvexFillPathCalls(0), |
| 1630 numGradients(0), | 1640 nonConvexFillPathArea(0.0f), |
| 1641 numRadialGradients(0), | |
| 1642 numLinearGradients(0), | |
| 1631 numPatterns(0), | 1643 numPatterns(0), |
| 1632 numDrawWithComplexClips(0), | 1644 numDrawWithComplexClips(0), |
| 1633 numBlurredShadows(0), | 1645 numBlurredShadows(0), |
| 1634 boundingBoxAreaTimesShadowBlurSquared(0.0), | 1646 boundingBoxAreaTimesShadowBlurSquared(0.0f), |
| 1635 boundingBoxPerimeterTimesShadowBlurSquared(0.0), | 1647 boundingBoxPerimeterTimesShadowBlurSquared(0.0f), |
| 1636 numFilters(0), | 1648 numFilters(0), |
| 1637 numGetImageDataCalls(0), | 1649 numGetImageDataCalls(0), |
| 1638 areaGetImageDataCalls(0.0), | 1650 areaGetImageDataCalls(0.0), |
| 1639 numPutImageDataCalls(0), | 1651 numPutImageDataCalls(0), |
| 1640 areaPutImageDataCalls(0.0), | 1652 areaPutImageDataCalls(0.0), |
| 1641 numClearRectCalls(0), | 1653 numClearRectCalls(0), |
| 1642 numDrawFocusCalls(0), | 1654 numDrawFocusCalls(0), |
| 1643 numFramesSinceReset(0) {} | 1655 numFramesSinceReset(0) {} |
| 1644 | 1656 |
| 1657 | |
| 1658 float BaseRenderingContext2D::estimateRenderingCost(ExpensiveCanvasHeuristicPara meters::RenderingModeCostIndex index) const | |
| 1659 { | |
| 1660 float basicCostOfDrawCalls = | |
| 1661 ExpensiveCanvasHeuristicParameters::FillRectFixedCost[index] * m_usageCo unters.numDrawCalls[BaseRenderingContext2D::FillRect] + | |
| 1662 ExpensiveCanvasHeuristicParameters::FillConvexPathFixedCost[index] * (m_ usageCounters.numDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.n umNonConvexFillPathCalls) + | |
| 1663 ExpensiveCanvasHeuristicParameters::FillNonConvexPathFixedCost[index] * m_usageCounters.numNonConvexFillPathCalls + | |
| 1664 ExpensiveCanvasHeuristicParameters::FillTextFixedCost[index] * m_usageCo unters.numDrawCalls[BaseRenderingContext2D::FillText] + | |
| 1665 | |
| 1666 ExpensiveCanvasHeuristicParameters::StrokeRectFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokeRect] + | |
| 1667 ExpensiveCanvasHeuristicParameters::StrokePathFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokePath] + | |
| 1668 ExpensiveCanvasHeuristicParameters::StrokeTextFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokeText] + | |
| 1669 | |
| 1670 ExpensiveCanvasHeuristicParameters::FillRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillRect] + | |
| 1671 ExpensiveCanvasHeuristicParameters::FillConvexPathVariableCostPerArea[in dex] * (m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillPat h] - m_usageCounters.nonConvexFillPathArea) + | |
| 1672 ExpensiveCanvasHeuristicParameters::FillNonConvexPathVariableCostPerArea [index] * m_usageCounters.nonConvexFillPathArea + | |
| 1673 ExpensiveCanvasHeuristicParameters::FillTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillText] + | |
| 1674 | |
| 1675 ExpensiveCanvasHeuristicParameters::StrokeRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeRect] + | |
| 1676 ExpensiveCanvasHeuristicParameters::StrokePathVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokePath] + | |
| 1677 ExpensiveCanvasHeuristicParameters::StrokeTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeText] + | |
| 1678 | |
| 1679 ExpensiveCanvasHeuristicParameters::PutImageDataFixedCost[index] * m_usa geCounters.numPutImageDataCalls + | |
| 1680 ExpensiveCanvasHeuristicParameters::PutImageDataVariableCostPerArea[inde x] * m_usageCounters.areaPutImageDataCalls + | |
| 1681 | |
| 1682 ExpensiveCanvasHeuristicParameters::DrawSVGImageFixedCost[index] * m_usa geCounters.numDrawCalls[BaseRenderingContext2D::DrawVectorImage] + | |
| 1683 ExpensiveCanvasHeuristicParameters::DrawPNGImageFixedCost[index] * m_usa geCounters.numDrawCalls[BaseRenderingContext2D::DrawBitmapImage] + | |
| 1684 | |
| 1685 ExpensiveCanvasHeuristicParameters::DrawSVGImageVariableCostPerArea[inde x] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawVector Image] + | |
| 1686 ExpensiveCanvasHeuristicParameters::DrawPNGImageVariableCostPerArea[inde x] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawBitmap Image]; | |
| 1687 | |
| 1688 float fillTypeAdjustment = | |
| 1689 ExpensiveCanvasHeuristicParameters::PatternFillTypeFixedCost[index] * m_ usageCounters.numPatterns + | |
| 1690 ExpensiveCanvasHeuristicParameters::LinearGradientFillTypeFixedCost[inde x] * m_usageCounters.numLinearGradients + | |
| 1691 ExpensiveCanvasHeuristicParameters::RadialGradientFillTypeFixedCost[inde x] * m_usageCounters.numRadialGradients + | |
| 1692 | |
| 1693 ExpensiveCanvasHeuristicParameters::PatternFillTypeVariableCostPerArea[i ndex] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::PatternF illType] + | |
| 1694 ExpensiveCanvasHeuristicParameters::LinearGradientFillVariableCostPerAre a[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Linea rGradientFillType] + | |
| 1695 ExpensiveCanvasHeuristicParameters::RadialGradientFillVariableCostPerAre a[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Radia lGradientFillType]; | |
| 1696 | |
| 1697 float shadowAdjustment = | |
| 1698 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * m_usageCoun ters.numBlurredShadows + | |
| 1699 ExpensiveCanvasHeuristicParameters::ShadowVariableCostPerAreaTimesShadow BlurSquared[index] * m_usageCounters.boundingBoxAreaTimesShadowBlurSquared; | |
| 1700 | |
| 1701 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment; | |
| 1702 } | |
| 1703 | |
| 1645 } // namespace blink | 1704 } // namespace blink |
| OLD | NEW |