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

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

Issue 2210123002: Improved heuristic for disable acceleration. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable trackDrawCall when Canvas 2D Dynamic Rendering Mode Switching is disabled Created 4 years, 4 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/parser/CSSParser.h" 10 #include "core/css/parser/CSSParser.h"
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
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)
1525 { 1530 {
1531 if (!RuntimeEnabledFeatures::enableCanvas2dDynamicRenderingModeSwitchingEnab led()) {
1532 // Rendering mode switching is disabled so no need to track the usage
1533 return;
1534 }
1535
1526 m_usageCounters.numDrawCalls[callType]++; 1536 m_usageCounters.numDrawCalls[callType]++;
1527 1537
1528 double boundingRectWidth = static_cast<double>(width); 1538 float boundingRectWidth = static_cast<float>(width);
1529 double boundingRectHeight = static_cast<double>(height); 1539 float boundingRectHeight = static_cast<float>(height);
1530 double boundingRectArea = boundingRectWidth * boundingRectHeight; 1540 float boundingRectArea = boundingRectWidth * boundingRectHeight;
1531 double boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRe ctHeight); 1541 float boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRec tHeight);
1532 1542
1533 if (callType == FillText 1543 if (callType == FillText
1534 || callType == FillPath 1544 || callType == FillPath
1535 || callType == StrokeText 1545 || callType == StrokeText
1536 || callType == StrokePath 1546 || callType == StrokePath
1537 || callType == FillRect 1547 || callType == FillRect
1538 || callType == StrokeRect) { 1548 || callType == StrokeRect) {
1539 1549
1540 SkPath skPath; 1550 SkPath skPath;
1541 if (path2d) { 1551 if (path2d) {
1542 skPath = path2d->path().getSkPath(); 1552 skPath = path2d->path().getSkPath();
1543 } else { 1553 } else {
1544 skPath = m_path.getSkPath(); 1554 skPath = m_path.getSkPath();
1545 } 1555 }
1546 1556
1547 if (callType == FillPath && !(skPath.getConvexity() == SkPath::kConvex_C onvexity)) { 1557
1548 m_usageCounters.numNonConvexFillPathCalls++; 1558 if (!(callType == FillRect || callType == StrokeRect || callType == Draw VectorImage || callType == DrawBitmapImage)) {
1559 // The correct width and height were not passed as parameters
1560 const SkRect& boundingRect = skPath.getBounds();
1561 boundingRectWidth = static_cast<float>(std::abs(boundingRect.width() ));
1562 boundingRectHeight = static_cast<float>(std::abs(boundingRect.height ()));
1563 boundingRectArea = boundingRectWidth * boundingRectHeight;
1564 boundingRectPerimeter = 2.0 * boundingRectWidth + 2.0 * boundingRect Height;
1549 } 1565 }
1550 1566
1551 if (!(callType == FillRect || callType == StrokeRect || callType == Draw Image)) { 1567 if (callType == FillPath && skPath.getConvexity() != SkPath::kConvex_Con vexity) {
1552 // The correct width and height were not passed as parameters 1568 m_usageCounters.numNonConvexFillPathCalls++;
1553 const SkRect& boundingRect = skPath.getBounds(); 1569 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 } 1570 }
1559 1571
1560 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter; 1572 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter;
1561 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea; 1573 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea;
1562 1574
1563 CanvasStyle* canvasStyle; 1575 CanvasStyle* canvasStyle;
1564 if (callType == FillText || callType == FillPath || callType == FillRect ) { 1576 if (callType == FillText || callType == FillPath || callType == FillRect ) {
1565 canvasStyle = state().fillStyle(); 1577 canvasStyle = state().fillStyle();
1566 } else { 1578 } else {
1567 canvasStyle = state().strokeStyle(); 1579 canvasStyle = state().strokeStyle();
1568 } 1580 }
1569 1581
1570 CanvasGradient* gradient = canvasStyle->getCanvasGradient(); 1582 CanvasGradient* gradient = canvasStyle->getCanvasGradient();
1571 if (gradient) { 1583 if (gradient) {
1572 m_usageCounters.numGradients++; 1584
1573 if (gradient->getGradient()->isRadial()) { 1585 if (gradient->getGradient()->isRadial()) {
1586 m_usageCounters.numRadialGradients++;
1574 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: RadialGradientFillType] += boundingRectArea; 1587 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: RadialGradientFillType] += boundingRectArea;
1575 } else { 1588 } else {
1589 m_usageCounters.numLinearGradients++;
1576 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: LinearGradientFillType] += boundingRectArea; 1590 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D:: LinearGradientFillType] += boundingRectArea;
1577 } 1591 }
1578 } else if (canvasStyle->getCanvasPattern()) { 1592 } else if (canvasStyle->getCanvasPattern()) {
1579 m_usageCounters.numPatterns++; 1593 m_usageCounters.numPatterns++;
1580 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Patt ernFillType] += boundingRectArea; 1594 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Patt ernFillType] += boundingRectArea;
1581 } else { 1595 } else {
1582 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Colo rFillType] += boundingRectArea; 1596 m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Colo rFillType] += boundingRectArea;
1583 } 1597 }
1584 } 1598 }
1585 1599
1586 if (callType == DrawImage) { 1600 if (callType == DrawVectorImage || callType == DrawBitmapImage) {
1587 m_usageCounters.boundingBoxPerimeterDrawCalls[DrawImage] += boundingRect Perimeter; 1601 m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectP erimeter;
1588 m_usageCounters.boundingBoxAreaDrawCalls[DrawImage] += boundingRectArea; 1602 m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea;
1589 } 1603 }
1590 1604
1591 if (callType == FillText 1605 if (callType == FillText
1592 || callType == FillPath 1606 || callType == FillPath
1593 || callType == StrokeText 1607 || callType == StrokeText
1594 || callType == StrokePath 1608 || callType == StrokePath
1595 || callType == FillRect 1609 || callType == FillRect
1596 || callType == StrokeRect 1610 || callType == StrokeRect
1597 || callType == DrawImage) { 1611 || callType == DrawVectorImage
1612 || callType == DrawBitmapImage) {
1598 if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0 ) { 1613 if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0 ) {
1599 m_usageCounters.numBlurredShadows++; 1614 m_usageCounters.numBlurredShadows++;
1600 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRec tArea * state().shadowBlur() * state().shadowBlur(); 1615 m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRec tArea * state().shadowBlur() * state().shadowBlur();
1601 m_usageCounters.boundingBoxPerimeterTimesShadowBlurSquared += boundi ngRectPerimeter * state().shadowBlur() * state().shadowBlur(); 1616 m_usageCounters.boundingBoxPerimeterTimesShadowBlurSquared += boundi ngRectPerimeter * state().shadowBlur() * state().shadowBlur();
1602 } 1617 }
1603 } 1618 }
1604 1619
1605 if (state().hasComplexClip()) { 1620 if (state().hasComplexClip()) {
1606 m_usageCounters.numDrawWithComplexClips++; 1621 m_usageCounters.numDrawWithComplexClips++;
1607 } 1622 }
1608 1623
1609 if (stateHasFilter()) { 1624 if (stateHasFilter()) {
1610 m_usageCounters.numFilters++; 1625 m_usageCounters.numFilters++;
1611 } 1626 }
1612 } 1627 }
1613 1628
1614 const BaseRenderingContext2D::UsageCounters& BaseRenderingContext2D::getUsage() 1629 const BaseRenderingContext2D::UsageCounters& BaseRenderingContext2D::getUsage()
1615 { 1630 {
1616 return m_usageCounters; 1631 return m_usageCounters;
1617 } 1632 }
1618 1633
1619 DEFINE_TRACE(BaseRenderingContext2D) 1634 DEFINE_TRACE(BaseRenderingContext2D)
1620 { 1635 {
1621 visitor->trace(m_stateStack); 1636 visitor->trace(m_stateStack);
1622 } 1637 }
1623 1638
1624 BaseRenderingContext2D::UsageCounters::UsageCounters() : 1639 BaseRenderingContext2D::UsageCounters::UsageCounters() :
1625 numDrawCalls {0, 0, 0, 0, 0, 0}, 1640 numDrawCalls {0, 0, 0, 0, 0, 0, 0},
1626 boundingBoxPerimeterDrawCalls {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 1641 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}, 1642 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}, 1643 boundingBoxAreaFillType {0.0f, 0.0f, 0.0f, 0.0f},
1629 numNonConvexFillPathCalls(0), 1644 numNonConvexFillPathCalls(0),
1630 numGradients(0), 1645 nonConvexFillPathArea(0.0f),
1646 numRadialGradients(0),
1647 numLinearGradients(0),
1631 numPatterns(0), 1648 numPatterns(0),
1632 numDrawWithComplexClips(0), 1649 numDrawWithComplexClips(0),
1633 numBlurredShadows(0), 1650 numBlurredShadows(0),
1634 boundingBoxAreaTimesShadowBlurSquared(0.0), 1651 boundingBoxAreaTimesShadowBlurSquared(0.0f),
1635 boundingBoxPerimeterTimesShadowBlurSquared(0.0), 1652 boundingBoxPerimeterTimesShadowBlurSquared(0.0f),
1636 numFilters(0), 1653 numFilters(0),
1637 numGetImageDataCalls(0), 1654 numGetImageDataCalls(0),
1638 areaGetImageDataCalls(0.0), 1655 areaGetImageDataCalls(0.0),
1639 numPutImageDataCalls(0), 1656 numPutImageDataCalls(0),
1640 areaPutImageDataCalls(0.0), 1657 areaPutImageDataCalls(0.0),
1641 numClearRectCalls(0), 1658 numClearRectCalls(0),
1642 numDrawFocusCalls(0), 1659 numDrawFocusCalls(0),
1643 numFramesSinceReset(0) {} 1660 numFramesSinceReset(0) {}
1644 1661
1662
1663 float BaseRenderingContext2D::estimateRenderingCost(ExpensiveCanvasHeuristicPara meters::RenderingModeCostIndex index) const
1664 {
1665 float basicCostOfDrawCalls =
1666 ExpensiveCanvasHeuristicParameters::FillRectFixedCost[index] * m_usageCo unters.numDrawCalls[BaseRenderingContext2D::FillRect] +
1667 ExpensiveCanvasHeuristicParameters::FillConvexPathFixedCost[index] * (m_ usageCounters.numDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.n umNonConvexFillPathCalls) +
1668 ExpensiveCanvasHeuristicParameters::FillNonConvexPathFixedCost[index] * m_usageCounters.numNonConvexFillPathCalls +
1669 ExpensiveCanvasHeuristicParameters::FillTextFixedCost[index] * m_usageCo unters.numDrawCalls[BaseRenderingContext2D::FillText] +
1670
1671 ExpensiveCanvasHeuristicParameters::StrokeRectFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokeRect] +
1672 ExpensiveCanvasHeuristicParameters::StrokePathFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokePath] +
1673 ExpensiveCanvasHeuristicParameters::StrokeTextFixedCost[index] * m_usage Counters.numDrawCalls[BaseRenderingContext2D::StrokeText] +
1674
1675 ExpensiveCanvasHeuristicParameters::FillRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillRect] +
1676 ExpensiveCanvasHeuristicParameters::FillConvexPathVariableCostPerArea[in dex] * (m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillPat h] - m_usageCounters.nonConvexFillPathArea) +
1677 ExpensiveCanvasHeuristicParameters::FillNonConvexPathVariableCostPerArea [index] * m_usageCounters.nonConvexFillPathArea +
1678 ExpensiveCanvasHeuristicParameters::FillTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillText] +
1679
1680 ExpensiveCanvasHeuristicParameters::StrokeRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeRect] +
1681 ExpensiveCanvasHeuristicParameters::StrokePathVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokePath] +
1682 ExpensiveCanvasHeuristicParameters::StrokeTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeText] +
1683
1684 ExpensiveCanvasHeuristicParameters::PutImageDataFixedCost[index] * m_usa geCounters.numPutImageDataCalls +
1685 ExpensiveCanvasHeuristicParameters::PutImageDataVariableCostPerArea[inde x] * m_usageCounters.areaPutImageDataCalls +
1686
1687 ExpensiveCanvasHeuristicParameters::DrawSVGImageFixedCost[index] * m_usa geCounters.numDrawCalls[BaseRenderingContext2D::DrawVectorImage] +
1688 ExpensiveCanvasHeuristicParameters::DrawPNGImageFixedCost[index] * m_usa geCounters.numDrawCalls[BaseRenderingContext2D::DrawBitmapImage] +
1689
1690 ExpensiveCanvasHeuristicParameters::DrawSVGImageVariableCostPerArea[inde x] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawVector Image] +
1691 ExpensiveCanvasHeuristicParameters::DrawPNGImageVariableCostPerArea[inde x] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawBitmap Image];
1692
1693 float fillTypeAdjustment =
1694 ExpensiveCanvasHeuristicParameters::PatternFillTypeFixedCost[index] * m_ usageCounters.numPatterns +
1695 ExpensiveCanvasHeuristicParameters::LinearGradientFillTypeFixedCost[inde x] * m_usageCounters.numLinearGradients +
1696 ExpensiveCanvasHeuristicParameters::RadialGradientFillTypeFixedCost[inde x] * m_usageCounters.numRadialGradients +
1697
1698 ExpensiveCanvasHeuristicParameters::PatternFillTypeVariableCostPerArea[i ndex] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::PatternF illType] +
1699 ExpensiveCanvasHeuristicParameters::LinearGradientFillVariableCostPerAre a[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Linea rGradientFillType] +
1700 ExpensiveCanvasHeuristicParameters::RadialGradientFillVariableCostPerAre a[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::Radia lGradientFillType];
1701
1702 float shadowAdjustment =
1703 ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * m_usageCoun ters.numBlurredShadows +
1704 ExpensiveCanvasHeuristicParameters::ShadowVariableCostPerAreaTimesShadow BlurSquared[index] * m_usageCounters.boundingBoxAreaTimesShadowBlurSquared;
1705
1706 return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment;
1707 }
1708
1645 } // namespace blink 1709 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698