// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/canvas2d/BaseRenderingContext2D.h"

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/css/parser/CSSParser.h"
#include "core/frame/ImageBitmap.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
#include "core/offscreencanvas/OffscreenCanvas.h"
#include "modules/canvas2d/CanvasGradient.h"
#include "modules/canvas2d/CanvasPattern.h"
#include "modules/canvas2d/CanvasStyle.h"
#include "modules/canvas2d/Path2D.h"
#include "platform/Histogram.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/graphics/Color.h"
#include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
#include "platform/graphics/Image.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/StrokeData.h"
#include "platform/graphics/skia/SkiaUtils.h"

namespace blink {

BaseRenderingContext2D::BaseRenderingContext2D()
    : m_clipAntialiasing(NotAntiAliased)
{
    m_stateStack.append(CanvasRenderingContext2DState::create());
}

BaseRenderingContext2D::~BaseRenderingContext2D()
{
}

CanvasRenderingContext2DState& BaseRenderingContext2D::modifiableState()
{
    realizeSaves();
    return *m_stateStack.last();
}

void BaseRenderingContext2D::realizeSaves()
{
    validateStateStack();
    if (state().hasUnrealizedSaves()) {
        ASSERT(m_stateStack.size() >= 1);
        // Reduce the current state's unrealized count by one now,
        // to reflect the fact we are saving one state.
        m_stateStack.last()->restore();
        m_stateStack.append(CanvasRenderingContext2DState::create(state(), CanvasRenderingContext2DState::DontCopyClipList));
        // Set the new state's unrealized count to 0, because it has no outstanding saves.
        // We need to do this explicitly because the copy constructor and operator= used
        // by the Vector operations copy the unrealized count from the previous state (in
        // turn necessary to support correct resizing and unwinding of the stack).
        m_stateStack.last()->resetUnrealizedSaveCount();
        SkCanvas* canvas = drawingCanvas();
        if (canvas)
            canvas->save();
        validateStateStack();
    }
}

void BaseRenderingContext2D::save()
{
    m_stateStack.last()->save();
}

void BaseRenderingContext2D::restore()
{
    validateStateStack();
    if (state().hasUnrealizedSaves()) {
        // We never realized the save, so just record that it was unnecessary.
        m_stateStack.last()->restore();
        return;
    }
    ASSERT(m_stateStack.size() >= 1);
    if (m_stateStack.size() <= 1)
        return;
    m_path.transform(state().transform());
    m_stateStack.removeLast();
    m_stateStack.last()->clearResolvedFilter();
    m_path.transform(state().transform().inverse());
    SkCanvas* c = drawingCanvas();
    if (c)
        c->restore();

    validateStateStack();
}

void BaseRenderingContext2D::restoreMatrixClipStack(SkCanvas* c) const
{
    if (!c)
        return;
    HeapVector<Member<CanvasRenderingContext2DState>>::const_iterator currState;
    DCHECK(m_stateStack.begin() < m_stateStack.end());
    for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currState++) {
        CHECK(currState->get());
        c->setMatrix(SkMatrix::I());
        currState->get()->playbackClips(c);
        c->setMatrix(affineTransformToSkMatrix(currState->get()->transform()));
        c->save();
    }
    c->restore();
    validateStateStack();
}

static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCanvasGradientOrCanvasPattern& returnValue)
{
    if (CanvasGradient* gradient = style->getCanvasGradient()) {
        returnValue.setCanvasGradient(gradient);
        return;
    }
    if (CanvasPattern* pattern = style->getCanvasPattern()) {
        returnValue.setCanvasPattern(pattern);
        return;
    }
    returnValue.setString(style->color());
}

void BaseRenderingContext2D::strokeStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
{
    convertCanvasStyleToUnionType(state().strokeStyle(), returnValue);
}

void BaseRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& style)
{
    ASSERT(!style.isNull());

    String colorString;
    CanvasStyle* canvasStyle = nullptr;
    if (style.isString()) {
        colorString = style.getAsString();
        if (colorString == state().unparsedStrokeColor())
            return;
        Color parsedColor = 0;
        if (!parseColorOrCurrentColor(parsedColor, colorString))
            return;
        if (state().strokeStyle()->isEquivalentRGBA(parsedColor.rgb())) {
            modifiableState().setUnparsedStrokeColor(colorString);
            return;
        }
        canvasStyle = CanvasStyle::createFromRGBA(parsedColor.rgb());
    } else if (style.isCanvasGradient()) {
        canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient());
    } else if (style.isCanvasPattern()) {
        CanvasPattern* canvasPattern = style.getAsCanvasPattern();

        if (originClean() && !canvasPattern->originClean())
            setOriginTainted();

        canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
    }

    ASSERT(canvasStyle);

    modifiableState().setStrokeStyle(canvasStyle);
    modifiableState().setUnparsedStrokeColor(colorString);
    modifiableState().clearResolvedFilter();
}

void BaseRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
{
    convertCanvasStyleToUnionType(state().fillStyle(), returnValue);
}

void BaseRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvasPattern& style)
{
    ASSERT(!style.isNull());
    validateStateStack();
    String colorString;
    CanvasStyle* canvasStyle = nullptr;
    if (style.isString()) {
        colorString = style.getAsString();
        if (colorString == state().unparsedFillColor())
            return;
        Color parsedColor = 0;
        if (!parseColorOrCurrentColor(parsedColor, colorString))
            return;
        if (state().fillStyle()->isEquivalentRGBA(parsedColor.rgb())) {
            modifiableState().setUnparsedFillColor(colorString);
            return;
        }
        canvasStyle = CanvasStyle::createFromRGBA(parsedColor.rgb());
    } else if (style.isCanvasGradient()) {
        canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient());
    } else if (style.isCanvasPattern()) {
        CanvasPattern* canvasPattern = style.getAsCanvasPattern();

        if (originClean() && !canvasPattern->originClean())
            setOriginTainted();
        if (canvasPattern->getPattern()->isTextureBacked())
            disableDeferral(DisableDeferralReasonUsingTextureBackedPattern);
        canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
    }

    ASSERT(canvasStyle);
    modifiableState().setFillStyle(canvasStyle);
    modifiableState().setUnparsedFillColor(colorString);
    modifiableState().clearResolvedFilter();
}

double BaseRenderingContext2D::lineWidth() const
{
    return state().lineWidth();
}

void BaseRenderingContext2D::setLineWidth(double width)
{
    if (!std::isfinite(width) || width <= 0)
        return;
    if (state().lineWidth() == width)
        return;
    modifiableState().setLineWidth(width);
}

String BaseRenderingContext2D::lineCap() const
{
    return lineCapName(state().getLineCap());
}

void BaseRenderingContext2D::setLineCap(const String& s)
{
    LineCap cap;
    if (!parseLineCap(s, cap))
        return;
    if (state().getLineCap() == cap)
        return;
    modifiableState().setLineCap(cap);
}

String BaseRenderingContext2D::lineJoin() const
{
    return lineJoinName(state().getLineJoin());
}

void BaseRenderingContext2D::setLineJoin(const String& s)
{
    LineJoin join;
    if (!parseLineJoin(s, join))
        return;
    if (state().getLineJoin() == join)
        return;
    modifiableState().setLineJoin(join);
}

double BaseRenderingContext2D::miterLimit() const
{
    return state().miterLimit();
}

void BaseRenderingContext2D::setMiterLimit(double limit)
{
    if (!std::isfinite(limit) || limit <= 0)
        return;
    if (state().miterLimit() == limit)
        return;
    modifiableState().setMiterLimit(limit);
}

double BaseRenderingContext2D::shadowOffsetX() const
{
    return state().shadowOffset().width();
}

void BaseRenderingContext2D::setShadowOffsetX(double x)
{
    if (!std::isfinite(x))
        return;
    if (state().shadowOffset().width() == x)
        return;
    modifiableState().setShadowOffsetX(x);
}

double BaseRenderingContext2D::shadowOffsetY() const
{
    return state().shadowOffset().height();
}

void BaseRenderingContext2D::setShadowOffsetY(double y)
{
    if (!std::isfinite(y))
        return;
    if (state().shadowOffset().height() == y)
        return;
    modifiableState().setShadowOffsetY(y);
}

double BaseRenderingContext2D::shadowBlur() const
{
    return state().shadowBlur();
}

void BaseRenderingContext2D::setShadowBlur(double blur)
{
    if (!std::isfinite(blur) || blur < 0)
        return;
    if (state().shadowBlur() == blur)
        return;
    modifiableState().setShadowBlur(blur);
}

String BaseRenderingContext2D::shadowColor() const
{
    return Color(state().shadowColor()).serialized();
}

void BaseRenderingContext2D::setShadowColor(const String& colorString)
{
    Color color;
    if (!parseColorOrCurrentColor(color, colorString))
        return;
    if (state().shadowColor() == color)
        return;
    modifiableState().setShadowColor(color.rgb());
}

const Vector<double>& BaseRenderingContext2D::getLineDash() const
{
    return state().lineDash();
}

static bool lineDashSequenceIsValid(const Vector<double>& dash)
{
    for (size_t i = 0; i < dash.size(); i++) {
        if (!std::isfinite(dash[i]) || dash[i] < 0)
            return false;
    }
    return true;
}

void BaseRenderingContext2D::setLineDash(const Vector<double>& dash)
{
    if (!lineDashSequenceIsValid(dash))
        return;
    modifiableState().setLineDash(dash);
}

double BaseRenderingContext2D::lineDashOffset() const
{
    return state().lineDashOffset();
}

void BaseRenderingContext2D::setLineDashOffset(double offset)
{
    if (!std::isfinite(offset) || state().lineDashOffset() == offset)
        return;
    modifiableState().setLineDashOffset(offset);
}

double BaseRenderingContext2D::globalAlpha() const
{
    return state().globalAlpha();
}

void BaseRenderingContext2D::setGlobalAlpha(double alpha)
{
    if (!(alpha >= 0 && alpha <= 1))
        return;
    if (state().globalAlpha() == alpha)
        return;
    modifiableState().setGlobalAlpha(alpha);
}

String BaseRenderingContext2D::globalCompositeOperation() const
{
    return compositeOperatorName(compositeOperatorFromSkia(state().globalComposite()), blendModeFromSkia(state().globalComposite()));
}

void BaseRenderingContext2D::setGlobalCompositeOperation(const String& operation)
{
    CompositeOperator op = CompositeSourceOver;
    WebBlendMode blendMode = WebBlendModeNormal;
    if (!parseCompositeAndBlendOperator(operation, op, blendMode))
        return;
    SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode);
    if (state().globalComposite() == xfermode)
        return;
    modifiableState().setGlobalComposite(xfermode);
}

String BaseRenderingContext2D::filter() const
{
    return state().unparsedFilter();
}

void BaseRenderingContext2D::setFilter(const String& filterString)
{
    if (filterString == state().unparsedFilter())
        return;

    const CSSValue* filterValue = CSSParser::parseSingleValue(CSSPropertyFilter, filterString, CSSParserContext(HTMLStandardMode, nullptr));

    if (!filterValue || filterValue->isInitialValue() || filterValue->isInheritedValue())
        return;

    modifiableState().setUnparsedFilter(filterString);
    modifiableState().setFilter(filterValue);
    snapshotStateForFilter();
}

SVGMatrixTearOff* BaseRenderingContext2D::currentTransform() const
{
    return SVGMatrixTearOff::create(state().transform());
}

void BaseRenderingContext2D::setCurrentTransform(SVGMatrixTearOff* matrixTearOff)
{
    const AffineTransform& transform = matrixTearOff->value();
    setTransform(transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
}

void BaseRenderingContext2D::scale(double sx, double sy)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;

    if (!std::isfinite(sx) || !std::isfinite(sy))
        return;

    AffineTransform newTransform = state().transform();
    newTransform.scaleNonUniform(sx, sy);
    if (state().transform() == newTransform)
        return;

    modifiableState().setTransform(newTransform);
    if (!state().isTransformInvertible())
        return;

    c->scale(sx, sy);
    m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}

void BaseRenderingContext2D::rotate(double angleInRadians)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;

    if (!std::isfinite(angleInRadians))
        return;

    AffineTransform newTransform = state().transform();
    newTransform.rotateRadians(angleInRadians);
    if (state().transform() == newTransform)
        return;

    modifiableState().setTransform(newTransform);
    if (!state().isTransformInvertible())
        return;
    c->rotate(angleInRadians * (180.0 / piFloat));
    m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
}

void BaseRenderingContext2D::translate(double tx, double ty)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;
    if (!state().isTransformInvertible())
        return;

    if (!std::isfinite(tx) || !std::isfinite(ty))
        return;

    AffineTransform newTransform = state().transform();
    newTransform.translate(tx, ty);
    if (state().transform() == newTransform)
        return;

    modifiableState().setTransform(newTransform);
    if (!state().isTransformInvertible())
        return;
    c->translate(tx, ty);
    m_path.transform(AffineTransform().translate(-tx, -ty));
}

void BaseRenderingContext2D::transform(double m11, double m12, double m21, double m22, double dx, double dy)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;

    if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy))
        return;

    AffineTransform transform(m11, m12, m21, m22, dx, dy);
    AffineTransform newTransform = state().transform() * transform;
    if (state().transform() == newTransform)
        return;

    modifiableState().setTransform(newTransform);
    if (!state().isTransformInvertible())
        return;

    c->concat(affineTransformToSkMatrix(transform));
    m_path.transform(transform.inverse());
}

void BaseRenderingContext2D::resetTransform()
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;

    AffineTransform ctm = state().transform();
    bool invertibleCTM = state().isTransformInvertible();
    // It is possible that CTM is identity while CTM is not invertible.
    // When CTM becomes non-invertible, realizeSaves() can make CTM identity.
    if (ctm.isIdentity() && invertibleCTM)
        return;

    // resetTransform() resolves the non-invertible CTM state.
    modifiableState().resetTransform();
    c->setMatrix(affineTransformToSkMatrix(baseTransform()));

    if (invertibleCTM)
        m_path.transform(ctm);
    // When else, do nothing because all transform methods didn't update m_path when CTM became non-invertible.
    // It means that resetTransform() restores m_path just before CTM became non-invertible.
}

void BaseRenderingContext2D::setTransform(double m11, double m12, double m21, double m22, double dx, double dy)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return;

    if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy))
        return;

    resetTransform();
    transform(m11, m12, m21, m22, dx, dy);
}

void BaseRenderingContext2D::beginPath()
{
    m_path.clear();
}

static bool validateRectForCanvas(double& x, double& y, double& width, double& height)
{
    if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std::isfinite(height))
        return false;

    if (!width && !height)
        return false;

    if (width < 0) {
        width = -width;
        x -= width;
    }

    if (height < 0) {
        height = -height;
        y -= height;
    }

    return true;
}

bool BaseRenderingContext2D::isFullCanvasCompositeMode(SkXfermode::Mode op)
{
    // See 4.8.11.1.3 Compositing
    // CompositeSourceAtop and CompositeDestinationOut are not listed here as the platforms already
    // implement the specification's behavior.
    return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode;
}

static bool isPathExpensive(const Path& path)
{
    const SkPath& skPath = path.getSkPath();
    if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive && !skPath.isConvex())
        return true;

    if (skPath.countPoints() > ExpensiveCanvasHeuristicParameters::ExpensivePathPointCount)
        return true;

    return false;
}

void BaseRenderingContext2D::drawPathInternal(const Path& path, CanvasRenderingContext2DState::PaintType paintType, SkPath::FillType fillType)
{
    if (path.isEmpty())
        return;

    SkPath skPath = path.getSkPath();
    FloatRect bounds = path.boundingRect();
    skPath.setFillType(fillType);

    if (paintType == CanvasRenderingContext2DState::StrokePaintType)
        inflateStrokeRect(bounds);

    if (!drawingCanvas())
        return;

    if (draw(
        [&skPath, this](SkCanvas* c, const SkPaint* paint) // draw lambda
        {
            c->drawPath(skPath, *paint);
        },
        [](const SkIRect& rect) // overdraw test lambda
        {
            return false;
        }, bounds, paintType)) {
        if (isPathExpensive(path)) {
            ImageBuffer* buffer = imageBuffer();
            if (buffer)
                buffer->setHasExpensiveOp();
        }
    }
}

static SkPath::FillType parseWinding(const String& windingRuleString)
{
    if (windingRuleString == "nonzero")
        return SkPath::kWinding_FillType;
    if (windingRuleString == "evenodd")
        return SkPath::kEvenOdd_FillType;

    ASSERT_NOT_REACHED();
    return SkPath::kEvenOdd_FillType;
}

void BaseRenderingContext2D::fill(const String& windingRuleString)
{
    trackDrawCall(FillPath);
    drawPathInternal(m_path, CanvasRenderingContext2DState::FillPaintType, parseWinding(windingRuleString));
}

void BaseRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString)
{
    trackDrawCall(FillPath, domPath);
    drawPathInternal(domPath->path(), CanvasRenderingContext2DState::FillPaintType, parseWinding(windingRuleString));
}

void BaseRenderingContext2D::stroke()
{
    trackDrawCall(StrokePath);
    drawPathInternal(m_path, CanvasRenderingContext2DState::StrokePaintType);
}

void BaseRenderingContext2D::stroke(Path2D* domPath)
{
    trackDrawCall(StrokePath, domPath);
    drawPathInternal(domPath->path(), CanvasRenderingContext2DState::StrokePaintType);
}

void BaseRenderingContext2D::fillRect(double x, double y, double width, double height)
{
    trackDrawCall(FillRect, nullptr, width, height);
    if (!validateRectForCanvas(x, y, width, height))
        return;

    if (!drawingCanvas())
        return;

    SkRect rect = SkRect::MakeXYWH(x, y, width, height);
    draw(
        [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda
        {
            c->drawRect(rect, *paint);
        },
        [&rect, this](const SkIRect& clipBounds) // overdraw test lambda
        {
            return rectContainsTransformedRect(rect, clipBounds);
        }, rect, CanvasRenderingContext2DState::FillPaintType);
}

static void strokeRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const SkPaint* paint)
{
    ASSERT(paint->getStyle() == SkPaint::kStroke_Style);
    if ((rect.width() > 0) != (rect.height() > 0)) {
        // When stroking, we must skip the zero-dimension segments
        SkPath path;
        path.moveTo(rect.x(), rect.y());
        path.lineTo(rect.maxX(), rect.maxY());
        path.close();
        canvas->drawPath(path, *paint);
        return;
    }
    canvas->drawRect(rect, *paint);
}

void BaseRenderingContext2D::strokeRect(double x, double y, double width, double height)
{
    trackDrawCall(StrokeRect, nullptr, width, height);
    if (!validateRectForCanvas(x, y, width, height))
        return;

    if (!drawingCanvas())
        return;

    SkRect rect = SkRect::MakeXYWH(x, y, width, height);
    FloatRect bounds = rect;
    inflateStrokeRect(bounds);
    draw(
        [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda
        {
            strokeRectOnCanvas(rect, c, paint);
        },
        [](const SkIRect& clipBounds) // overdraw test lambda
        {
            return false;
        }, bounds, CanvasRenderingContext2DState::StrokePaintType);
}

void BaseRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
{
    SkCanvas* c = drawingCanvas();
    if (!c) {
        return;
    }
    if (!state().isTransformInvertible()) {
        return;
    }

    SkPath skPath = path.getSkPath();
    skPath.setFillType(parseWinding(windingRuleString));
    modifiableState().clipPath(skPath, m_clipAntialiasing);
    c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAliased);
    if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive && !skPath.isRect(0) && hasImageBuffer()) {
        imageBuffer()->setHasExpensiveOp();
    }
}

void BaseRenderingContext2D::clip(const String& windingRuleString)
{
    clipInternal(m_path, windingRuleString);
}

void BaseRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString)
{
    clipInternal(domPath->path(), windingRuleString);
}

bool BaseRenderingContext2D::isPointInPath(const double x, const double y, const String& windingRuleString)
{
    return isPointInPathInternal(m_path, x, y, windingRuleString);
}

bool BaseRenderingContext2D::isPointInPath(Path2D* domPath, const double x, const double y, const String& windingRuleString)
{
    return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
}

bool BaseRenderingContext2D::isPointInPathInternal(const Path& path, const double x, const double y, const String& windingRuleString)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return false;
    if (!state().isTransformInvertible())
        return false;

    FloatPoint point(x, y);
    if (!std::isfinite(point.x()) || !std::isfinite(point.y()))
        return false;
    AffineTransform ctm = state().transform();
    FloatPoint transformedPoint = ctm.inverse().mapPoint(point);

    return path.contains(transformedPoint, SkFillTypeToWindRule(parseWinding(windingRuleString)));
}

bool BaseRenderingContext2D::isPointInStroke(const double x, const double y)
{
    return isPointInStrokeInternal(m_path, x, y);
}

bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath, const double x, const double y)
{
    return isPointInStrokeInternal(domPath->path(), x, y);
}

bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path, const double x, const double y)
{
    SkCanvas* c = drawingCanvas();
    if (!c)
        return false;
    if (!state().isTransformInvertible())
        return false;

    FloatPoint point(x, y);
    if (!std::isfinite(point.x()) || !std::isfinite(point.y()))
        return false;
    AffineTransform ctm = state().transform();
    FloatPoint transformedPoint = ctm.inverse().mapPoint(point);

    StrokeData strokeData;
    strokeData.setThickness(state().lineWidth());
    strokeData.setLineCap(state().getLineCap());
    strokeData.setLineJoin(state().getLineJoin());
    strokeData.setMiterLimit(state().miterLimit());
    Vector<float> lineDash(state().lineDash().size());
    std::copy(state().lineDash().begin(), state().lineDash().end(), lineDash.begin());
    strokeData.setLineDash(lineDash, state().lineDashOffset());
    return path.strokeContains(transformedPoint, strokeData);
}

void BaseRenderingContext2D::clearRect(double x, double y, double width, double height)
{
    m_usageCounters.numClearRectCalls++;

    if (!validateRectForCanvas(x, y, width, height))
        return;

    SkCanvas* c = drawingCanvas();
    if (!c)
        return;
    if (!state().isTransformInvertible())
        return;

    SkIRect clipBounds;
    if (!c->getClipDeviceBounds(&clipBounds))
        return;

    SkPaint clearPaint;
    clearPaint.setXfermodeMode(SkXfermode::kClear_Mode);
    clearPaint.setStyle(SkPaint::kFill_Style);
    FloatRect rect(x, y, width, height);

    if (rectContainsTransformedRect(rect, clipBounds)) {
        checkOverdraw(rect, &clearPaint, CanvasRenderingContext2DState::NoImage, ClipFill);
        if (drawingCanvas())
            drawingCanvas()->drawRect(rect, clearPaint);
        didDraw(clipBounds);
    } else {
        SkIRect dirtyRect;
        if (computeDirtyRect(rect, clipBounds, &dirtyRect)) {
            c->drawRect(rect, clearPaint);
            didDraw(dirtyRect);
        }
    }
}

static inline FloatRect normalizeRect(const FloatRect& rect)
{
    return FloatRect(std::min(rect.x(), rect.maxX()),
        std::min(rect.y(), rect.maxY()),
        std::max(rect.width(), -rect.width()),
        std::max(rect.height(), -rect.height()));
}

static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* srcRect, FloatRect* dstRect)
{
    if (imageRect.contains(*srcRect))
        return;

    // Compute the src to dst transform
    FloatSize scale(dstRect->size().width() / srcRect->size().width(), dstRect->size().height() / srcRect->size().height());
    FloatPoint scaledSrcLocation = srcRect->location();
    scaledSrcLocation.scale(scale.width(), scale.height());
    FloatSize offset = dstRect->location() - scaledSrcLocation;

    srcRect->intersect(imageRect);

    // To clip the destination rectangle in the same proportion, transform the clipped src rect
    *dstRect = *srcRect;
    dstRect->scale(scale.width(), scale.height());
    dstRect->move(offset);
}

static inline CanvasImageSource* toImageSourceInternal(const CanvasImageSourceUnion& value, ExceptionState& exceptionState)
{
    if (value.isHTMLImageElement())
        return value.getAsHTMLImageElement();
    if (value.isHTMLVideoElement())
        return value.getAsHTMLVideoElement();
    if (value.isHTMLCanvasElement())
        return value.getAsHTMLCanvasElement();
    if (value.isImageBitmap()) {
        if (static_cast<ImageBitmap*>(value.getAsImageBitmap())->isNeutered()) {
            exceptionState.throwDOMException(InvalidStateError, String::format("The image source is detached"));
            return nullptr;
        }
        return value.getAsImageBitmap();
    }
    if (value.isOffscreenCanvas()) {
        if (static_cast<OffscreenCanvas*>(value.getAsOffscreenCanvas())->isNeutered()) {
            exceptionState.throwDOMException(InvalidStateError, String::format("The image source is detached"));
            return nullptr;
        }
        return value.getAsOffscreenCanvas();
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

void BaseRenderingContext2D::drawImage(ExecutionContext* executionContext, const CanvasImageSourceUnion& imageSource, double x, double y, ExceptionState& exceptionState)
{
    CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource, exceptionState);
    if (!imageSourceInternal)
        return;
    FloatSize defaultObjectSize(width(), height());
    FloatSize sourceRectSize = imageSourceInternal->elementSize(defaultObjectSize);
    FloatSize destRectSize = imageSourceInternal->defaultDestinationSize(defaultObjectSize);
    drawImage(executionContext, imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, destRectSize.width(), destRectSize.height(), exceptionState);
}

void BaseRenderingContext2D::drawImage(ExecutionContext* executionContext, const CanvasImageSourceUnion& imageSource,
    double x, double y, double width, double height, ExceptionState& exceptionState)
{
    CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource, exceptionState);
    if (!imageSourceInternal)
        return;
    FloatSize defaultObjectSize(this->width(), this->height());
    FloatSize sourceRectSize = imageSourceInternal->elementSize(defaultObjectSize);
    drawImage(executionContext, imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
}

void BaseRenderingContext2D::drawImage(ExecutionContext* executionContext, const CanvasImageSourceUnion& imageSource,
    double sx, double sy, double sw, double sh,
    double dx, double dy, double dw, double dh, ExceptionState& exceptionState)
{
    CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource, exceptionState);
    if (!imageSourceInternal)
        return;
    drawImage(executionContext, imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState);
}

bool BaseRenderingContext2D::shouldDrawImageAntialiased(const FloatRect& destRect) const
{
    if (!state().shouldAntialias())
        return false;
    SkCanvas* c = drawingCanvas();
    ASSERT(c);

    const SkMatrix &ctm = c->getTotalMatrix();
    // Don't disable anti-aliasing if we're rotated or skewed.
    if (!ctm.rectStaysRect())
        return true;
    // Check if the dimensions of the destination are "small" (less than one
    // device pixel). To prevent sudden drop-outs. Since we know that
    // kRectStaysRect_Mask is set, the matrix either has scale and no skew or
    // vice versa. We can query the kAffine_Mask flag to determine which case
    // it is.
    // FIXME: This queries the CTM while drawing, which is generally
    // discouraged. Always drawing with AA can negatively impact performance
    // though - that's why it's not always on.
    SkScalar widthExpansion, heightExpansion;
    if (ctm.getType() & SkMatrix::kAffine_Mask)
        widthExpansion = ctm[SkMatrix::kMSkewY], heightExpansion = ctm[SkMatrix::kMSkewX];
    else
        widthExpansion = ctm[SkMatrix::kMScaleX], heightExpansion = ctm[SkMatrix::kMScaleY];
    return destRect.width() * fabs(widthExpansion) < 1 || destRect.height() * fabs(heightExpansion) < 1;
}

static bool isDrawScalingDown(const FloatRect& srcRect, const FloatRect& dstRect, float xScaleSquared, float yScaleSquared)
{
    return dstRect.width() * dstRect.width() * xScaleSquared < srcRect.width() * srcRect.width()
        && dstRect.height() * dstRect.height() * yScaleSquared < srcRect.height() * srcRect.height();
}

void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint* paint)
{
    if (imageSource->isSVGSource()) {
        trackDrawCall(DrawVectorImage, nullptr, dstRect.width(), dstRect.height());
    } else {
        trackDrawCall(DrawBitmapImage, nullptr, dstRect.width(), dstRect.height());
    }

    int initialSaveCount = c->getSaveCount();
    SkPaint imagePaint = *paint;

    if (paint->getImageFilter()) {
        SkMatrix ctm = c->getTotalMatrix();
        SkMatrix invCtm;
        if (!ctm.invert(&invCtm)) {
            // There is an earlier check for invertibility, but the arithmetic
            // in AffineTransform is not exactly identical, so it is possible
            // for SkMatrix to find the transform to be non-invertible at this stage.
            // crbug.com/504687
            return;
        }
        c->save();
        c->concat(invCtm);
        SkRect bounds = dstRect;
        ctm.mapRect(&bounds);
        SkPaint layerPaint;
        layerPaint.setXfermode(sk_ref_sp(paint->getXfermode()));
        layerPaint.setImageFilter(paint->getImageFilter());

        c->saveLayer(&bounds, &layerPaint);
        c->concat(ctm);
        imagePaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
        imagePaint.setImageFilter(nullptr);
    }

    if (!imageSmoothingEnabled() && isDrawScalingDown(srcRect, dstRect, state().transform().xScaleSquared(), state().transform().yScaleSquared()))
        imagePaint.setFilterQuality(kLow_SkFilterQuality);

    if (!imageSource->isVideoElement()) {
        imagePaint.setAntiAlias(shouldDrawImageAntialiased(dstRect));
        image->draw(c, imagePaint, dstRect, srcRect, DoNotRespectImageOrientation, Image::DoNotClampImageToSourceRect);
    } else {
        c->save();
        c->clipRect(dstRect);
        c->translate(dstRect.x(), dstRect.y());
        c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height());
        c->translate(-srcRect.x(), -srcRect.y());
        HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource);
        video->paintCurrentFrame(c, IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())), &imagePaint);
    }

    c->restoreToCount(initialSaveCount);
}

bool shouldDisableDeferral(CanvasImageSource* imageSource, DisableDeferralReason* reason)
{
    ASSERT(reason);
    ASSERT(*reason == DisableDeferralReasonUnknown);

    if (imageSource->isVideoElement()) {
        *reason = DisableDeferralReasonDrawImageOfVideo;
        return true;
    }
    if (imageSource->isCanvasElement()) {
        HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(imageSource);
        if (canvas->isAnimated2D()) {
            *reason = DisableDeferralReasonDrawImageOfAnimated2dCanvas;
            return true;
        }
    }
    return false;
}

void BaseRenderingContext2D::drawImage(ExecutionContext* executionContext, CanvasImageSource* imageSource,
    double sx, double sy, double sw, double sh,
    double dx, double dy, double dw, double dh, ExceptionState& exceptionState)
{
    if (!drawingCanvas())
        return;

    RefPtr<Image> image;
    FloatSize defaultObjectSize(width(), height());
    SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
    if (!imageSource->isVideoElement()) {
        AccelerationHint hint = imageBuffer()->isAccelerated() ? PreferAcceleration : PreferNoAcceleration;
        image = imageSource->getSourceImageForCanvas(&sourceImageStatus, hint, SnapshotReasonDrawImage, defaultObjectSize);
        if (sourceImageStatus == UndecodableSourceImageStatus)
            exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
        if (!image || !image->width() || !image->height())
            return;
    } else {
        if (!static_cast<HTMLVideoElement*>(imageSource)->hasAvailableVideoFrame())
            return;
    }

    if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::isfinite(dh)
        || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)
        || !dw || !dh || !sw || !sh)
        return;

    FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
    FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
    FloatSize imageSize = imageSource->elementSize(defaultObjectSize);

    clipRectsToImageRect(FloatRect(FloatPoint(), imageSize), &srcRect, &dstRect);

    imageSource->adjustDrawRects(&srcRect, &dstRect);

    if (srcRect.isEmpty())
        return;

    DisableDeferralReason reason = DisableDeferralReasonUnknown;
    if (shouldDisableDeferral(imageSource, &reason))
        disableDeferral(reason);
    else if (image->isTextureBacked())
        disableDeferral(DisableDeferralDrawImageWithTextureBackedSourceImage);

    validateStateStack();

    // Heuristic for disabling acceleration based on anticipated texture upload overhead
    // See comments in ExpensiveCanvasHeuristicParameters.h for explanation.
    ImageBuffer* buffer = imageBuffer();
    if (buffer && buffer->isAccelerated() && !imageSource->isAccelerated()) {
        float srcArea = srcRect.width() * srcRect.height();
        if (srcArea > ExpensiveCanvasHeuristicParameters::DrawImageTextureUploadHardSizeLimit) {
            buffer->disableAcceleration();
        } else if (srcArea > ExpensiveCanvasHeuristicParameters::DrawImageTextureUploadSoftSizeLimit) {
            SkRect bounds = dstRect;
            SkMatrix ctm = drawingCanvas()->getTotalMatrix();
            ctm.mapRect(&bounds);
            float dstArea = dstRect.width() * dstRect.height();
            if (srcArea > dstArea * ExpensiveCanvasHeuristicParameters::DrawImageTextureUploadSoftSizeLimitScaleThreshold) {
                buffer->disableAcceleration();
            }
        }
    }

    validateStateStack();

    // TODO(xidachen): After collecting some data, come back and prune off
    // the ones that is not needed.
    Optional<ScopedUsHistogramTimer> timer;
    if (imageBuffer() && imageBuffer()->isAccelerated()) {
        if (imageSource->isVideoElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.GPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterVideoGPU);
        } else if (imageSource->isCanvasElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.GPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterCanvasGPU);
        } else if (imageSource->isSVGSource()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.GPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterSVGGPU);
        } else if (imageSource->isImageBitmap()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.GPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterImageBitmapGPU);
        } else {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersGPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.GPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterOthersGPU);
        }
    } else if (imageBuffer() && imageBuffer()->isRecording()) {
        if (imageSource->isVideoElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.DisplayList", 0, 10000000, 50));
            timer.emplace(scopedUsCounterVideoDisplayList);
        } else if (imageSource->isCanvasElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.DisplayList", 0, 10000000, 50));
            timer.emplace(scopedUsCounterCanvasDisplayList);
        } else if (imageSource->isSVGSource()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.DisplayList", 0, 10000000, 50));
            timer.emplace(scopedUsCounterSVGDisplayList);
        } else if (imageSource->isImageBitmap()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.DisplayList", 0, 10000000, 50));
            timer.emplace(scopedUsCounterImageBitmapDisplayList);
        } else {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersDisplayList, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.DisplayList", 0, 10000000, 50));
            timer.emplace(scopedUsCounterOthersDisplayList);
        }
    } else {
        if (imageSource->isVideoElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterVideoCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Video.CPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterVideoCPU);
        } else if (imageSource->isCanvasElement()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCanvasCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Canvas.CPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterCanvasCPU);
        } else if (imageSource->isSVGSource()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterSVGCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.SVG.CPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterSVGCPU);
        } else if (imageSource->isImageBitmap()) {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterImageBitmapCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.ImageBitmap.CPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterImageBitmapCPU);
        } else {
            DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterOthersCPU, new CustomCountHistogram("Blink.Canvas.DrawImage.Others.CPU", 0, 10000000, 50));
            timer.emplace(scopedUsCounterOthersCPU);
        }
    }

    draw(
        [this, &imageSource, &image, &srcRect, dstRect](SkCanvas* c, const SkPaint* paint) // draw lambda
        {
            drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, paint);
        },
        [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda
        {
            return rectContainsTransformedRect(dstRect, clipBounds);
        }, dstRect, CanvasRenderingContext2DState::ImagePaintType,
        imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : CanvasRenderingContext2DState::NonOpaqueImage);

    validateStateStack();

    bool isExpensive = false;

    if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && imageSource->isSVGSource())
        isExpensive = true;

    if (imageSize.width() * imageSize.height() > width() * height() * ExpensiveCanvasHeuristicParameters::ExpensiveImageSizeRatio)
        isExpensive = true;

    if (isExpensive) {
        ImageBuffer* buffer = imageBuffer();
        if (buffer)
            buffer->setHasExpensiveOp();
    }

    if (originClean() && wouldTaintOrigin(imageSource, executionContext))
        setOriginTainted();
}

void BaseRenderingContext2D::clearCanvas()
{
    FloatRect canvasRect(0, 0, width(), height());
    checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, ClipFill);
    SkCanvas* c = drawingCanvas();
    if (c)
        c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK);
}

bool BaseRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect, const SkIRect& transformedRect) const
{
    FloatQuad quad(rect);
    FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(), transformedRect.width(), transformedRect.height()));
    return state().transform().mapQuad(quad).containsQuad(transformedQuad);
}

CanvasGradient* BaseRenderingContext2D::createLinearGradient(double x0, double y0, double x1, double y1)
{
    CanvasGradient* gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
    return gradient;
}

CanvasGradient* BaseRenderingContext2D::createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1, ExceptionState& exceptionState)
{
    if (r0 < 0 || r1 < 0) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The %s provided is less than 0.", r0 < 0 ? "r0" : "r1"));
        return nullptr;
    }

    CanvasGradient* gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
    return gradient;
}

CanvasPattern* BaseRenderingContext2D::createPattern(ExecutionContext* executionContext, const CanvasImageSourceUnion& imageSource, const String& repetitionType, ExceptionState& exceptionState)
{
    CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource, exceptionState);
    if (!imageSourceInternal) {
        return nullptr;
    }

    return createPattern(executionContext, imageSourceInternal, repetitionType, exceptionState);
}

CanvasPattern* BaseRenderingContext2D::createPattern(ExecutionContext* executionContext, CanvasImageSource* imageSource, const String& repetitionType, ExceptionState& exceptionState)
{
    if (!imageSource) {
        return nullptr;
    }

    Pattern::RepeatMode repeatMode = CanvasPattern::parseRepetitionType(repetitionType, exceptionState);
    if (exceptionState.hadException())
        return nullptr;

    SourceImageStatus status;

    FloatSize defaultObjectSize(width(), height());
    RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(&status, PreferNoAcceleration, SnapshotReasonCreatePattern, defaultObjectSize);

    switch (status) {
    case NormalSourceImageStatus:
        break;
    case ZeroSizeCanvasSourceImageStatus:
        exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", imageSource->elementSize(defaultObjectSize).width() ? "height" : "width"));
        return nullptr;
    case UndecodableSourceImageStatus:
        exceptionState.throwDOMException(InvalidStateError, "Source image is in the 'broken' state.");
        return nullptr;
    case InvalidSourceImageStatus:
        imageForRendering = Image::nullImage();
        break;
    case IncompleteSourceImageStatus:
        return nullptr;
    default:
        ASSERT_NOT_REACHED();
        return nullptr;
    }
    ASSERT(imageForRendering);

    bool originClean = !wouldTaintOrigin(imageSource, executionContext);

    return CanvasPattern::create(imageForRendering.release(), repeatMode, originClean);
}

bool BaseRenderingContext2D::computeDirtyRect(const FloatRect& localRect, SkIRect* dirtyRect)
{
    SkIRect clipBounds;
    if (!drawingCanvas()->getClipDeviceBounds(&clipBounds))
        return false;
    return computeDirtyRect(localRect, clipBounds, dirtyRect);
}

bool BaseRenderingContext2D::computeDirtyRect(const FloatRect& localRect, const SkIRect& transformedClipBounds, SkIRect* dirtyRect)
{
    FloatRect canvasRect = state().transform().mapRect(localRect);

    if (alphaChannel(state().shadowColor())) {
        FloatRect shadowRect(canvasRect);
        shadowRect.move(state().shadowOffset());
        shadowRect.inflate(state().shadowBlur());
        canvasRect.unite(shadowRect);
    }

    SkIRect canvasIRect;
    static_cast<SkRect>(canvasRect).roundOut(&canvasIRect);
    if (!canvasIRect.intersect(transformedClipBounds))
        return false;

    if (dirtyRect)
        *dirtyRect = canvasIRect;

    return true;
}

ImageData* BaseRenderingContext2D::createImageData(ImageData* imageData, ExceptionState &exceptionState) const
{
    ImageData* result = ImageData::create(imageData->size());
    if (!result)
        exceptionState.throwRangeError("Out of memory at ImageData creation");
    return result;
}

ImageData* BaseRenderingContext2D::createImageData(double sw, double sh, ExceptionState& exceptionState) const
{
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
        return nullptr;
    }

    FloatSize logicalSize(fabs(sw), fabs(sh));
    if (!logicalSize.isExpressibleAsIntSize())
        return nullptr;

    IntSize size = expandedIntSize(logicalSize);
    if (size.width() < 1)
        size.setWidth(1);
    if (size.height() < 1)
        size.setHeight(1);

    ImageData* result = ImageData::create(size);
    if (!result)
        exceptionState.throwRangeError("Out of memory at ImageData creation");
    return result;
}

ImageData* BaseRenderingContext2D::getImageData(double sx, double sy, double sw, double sh, ExceptionState& exceptionState) const
{
    m_usageCounters.numGetImageDataCalls++;
    m_usageCounters.areaGetImageDataCalls += sw * sh;
    if (!originClean())
        exceptionState.throwSecurityError("The canvas has been tainted by cross-origin data.");
    else if (!sw || !sh)
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));

    if (exceptionState.hadException())
        return nullptr;

    if (sw < 0) {
        sx += sw;
        sw = -sw;
    }
    if (sh < 0) {
        sy += sh;
        sh = -sh;
    }

    FloatRect logicalRect(sx, sy, sw, sh);
    if (logicalRect.width() < 1)
        logicalRect.setWidth(1);
    if (logicalRect.height() < 1)
        logicalRect.setHeight(1);
    if (!logicalRect.isExpressibleAsIntRect())
        return nullptr;

    Optional<ScopedUsHistogramTimer> timer;
    if (imageBuffer() && imageBuffer()->isAccelerated()) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterGPU, new CustomCountHistogram("Blink.Canvas.GetImageData.GPU", 0, 10000000, 50));
        timer.emplace(scopedUsCounterGPU);
    } else if (imageBuffer() && imageBuffer()->isRecording()) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterDisplayList, new CustomCountHistogram("Blink.Canvas.GetImageData.DisplayList", 0, 10000000, 50));
        timer.emplace(scopedUsCounterDisplayList);
    } else {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCPU, new CustomCountHistogram("Blink.Canvas.GetImageData.CPU", 0, 10000000, 50));
        timer.emplace(scopedUsCounterCPU);
    }

    IntRect imageDataRect = enclosingIntRect(logicalRect);
    ImageBuffer* buffer = imageBuffer();
    if (!buffer || isContextLost()) {
        ImageData* result = ImageData::create(imageDataRect.size());
        if (!result)
            exceptionState.throwRangeError("Out of memory at ImageData creation");
        return result;
    }

    WTF::ArrayBufferContents contents;
    if (!buffer->getImageData(Unmultiplied, imageDataRect, contents)) {
        exceptionState.throwRangeError("Out of memory at ImageData creation");
        return nullptr;
    }

    DOMArrayBuffer* arrayBuffer = DOMArrayBuffer::create(contents);
    return ImageData::create(
        imageDataRect.size(),
        DOMUint8ClampedArray::create(arrayBuffer, 0, arrayBuffer->byteLength()));
}

void BaseRenderingContext2D::putImageData(ImageData* data, double dx, double dy, ExceptionState& exceptionState)
{
    putImageData(data, dx, dy, 0, 0, data->width(), data->height(), exceptionState);
}

void BaseRenderingContext2D::putImageData(ImageData* data, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ExceptionState& exceptionState)
{
    m_usageCounters.numPutImageDataCalls++;
    m_usageCounters.areaPutImageDataCalls += dirtyWidth * dirtyHeight;
    if (data->data()->bufferBase()->isNeutered()) {
        exceptionState.throwDOMException(InvalidStateError, "The source data has been neutered.");
        return;
    }
    ImageBuffer* buffer = imageBuffer();
    if (!buffer)
        return;

    if (dirtyWidth < 0) {
        dirtyX += dirtyWidth;
        dirtyWidth = -dirtyWidth;
    }

    if (dirtyHeight < 0) {
        dirtyY += dirtyHeight;
        dirtyHeight = -dirtyHeight;
    }

    FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
    clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
    IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
    IntRect destRect = enclosingIntRect(clipRect);
    destRect.move(destOffset);
    destRect.intersect(IntRect(IntPoint(), buffer->size()));
    if (destRect.isEmpty())
        return;

    Optional<ScopedUsHistogramTimer> timer;
    if (imageBuffer() && imageBuffer()->isAccelerated()) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterGPU, new CustomCountHistogram("Blink.Canvas.PutImageData.GPU", 0, 10000000, 50));
        timer.emplace(scopedUsCounterGPU);
    } else if (imageBuffer() && imageBuffer()->isRecording()) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterDisplayList, new CustomCountHistogram("Blink.Canvas.PutImageData.DisplayList", 0, 10000000, 50));
        timer.emplace(scopedUsCounterDisplayList);
    } else {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scopedUsCounterCPU, new CustomCountHistogram("Blink.Canvas.PutImageData.CPU", 0, 10000000, 50));
        timer.emplace(scopedUsCounterCPU);
    }

    IntRect sourceRect(destRect);
    sourceRect.move(-destOffset);

    checkOverdraw(destRect, 0, CanvasRenderingContext2DState::NoImage, UntransformedUnclippedFill);

    buffer->putByteArray(Unmultiplied, data->data()->data(), IntSize(data->width(), data->height()), sourceRect, IntPoint(destOffset));

    didDraw(destRect);
}

void BaseRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
{
    // Fast approximation of the stroke's bounding rect.
    // This yields a slightly oversized rect but is very fast
    // compared to Path::strokeBoundingRect().
    static const double root2 = sqrtf(2);
    double delta = state().lineWidth() / 2;
    if (state().getLineJoin() == MiterJoin)
        delta *= state().miterLimit();
    else if (state().getLineCap() == SquareCap)
        delta *= root2;

    rect.inflate(delta);
}

bool BaseRenderingContext2D::imageSmoothingEnabled() const
{
    return state().imageSmoothingEnabled();
}

void BaseRenderingContext2D::setImageSmoothingEnabled(bool enabled)
{
    if (enabled == state().imageSmoothingEnabled())
        return;

    modifiableState().setImageSmoothingEnabled(enabled);
}

String BaseRenderingContext2D::imageSmoothingQuality() const
{
    return state().imageSmoothingQuality();
}

void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality)
{
    if (quality == state().imageSmoothingQuality())
        return;

    modifiableState().setImageSmoothingQuality(quality);
}

void BaseRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint* paint, CanvasRenderingContext2DState::ImageType imageType, DrawType drawType)
{
    SkCanvas* c = drawingCanvas();
    if (!c || !imageBuffer()->isRecording())
        return;

    SkRect deviceRect;
    if (drawType == UntransformedUnclippedFill) {
        deviceRect = rect;
    } else {
        ASSERT(drawType == ClipFill);
        if (state().hasComplexClip())
            return;

        SkIRect skIBounds;
        if (!c->getClipDeviceBounds(&skIBounds))
            return;
        deviceRect = SkRect::Make(skIBounds);
    }

    const SkImageInfo& imageInfo = c->imageInfo();
    if (!deviceRect.contains(SkRect::MakeWH(imageInfo.width(), imageInfo.height())))
        return;

    bool isSourceOver = true;
    unsigned alpha = 0xFF;
    if (paint) {
        if (paint->getLooper() || paint->getImageFilter() || paint->getMaskFilter())
            return;

        SkXfermode* xfermode = paint->getXfermode();
        if (xfermode) {
            SkXfermode::Mode mode;
            if (xfermode->asMode(&mode)) {
                isSourceOver = mode == SkXfermode::kSrcOver_Mode;
                if (!isSourceOver && mode != SkXfermode::kSrc_Mode && mode != SkXfermode::kClear_Mode)
                    return; // The code below only knows how to handle Src, SrcOver, and Clear
            } else {
                // unknown xfermode
                ASSERT_NOT_REACHED();
                return;
            }
        }

        alpha = paint->getAlpha();

        if (isSourceOver && imageType == CanvasRenderingContext2DState::NoImage) {
            SkShader* shader = paint->getShader();
            if (shader) {
                if (shader->isOpaque() && alpha == 0xFF)
                    imageBuffer()->willOverwriteCanvas();
                return;
            }
        }
    }

    if (isSourceOver) {
        // With source over, we need to certify that alpha == 0xFF for all pixels
        if (imageType == CanvasRenderingContext2DState::NonOpaqueImage)
            return;
        if (alpha < 0xFF)
            return;
    }

    imageBuffer()->willOverwriteCanvas();
}

void BaseRenderingContext2D::trackDrawCall(DrawCallType callType, Path2D* path2d, int width, int height)
{
    if (!RuntimeEnabledFeatures::enableCanvas2dDynamicRenderingModeSwitchingEnabled()) {
        // Rendering mode switching is disabled so no need to track the usage
        return;
    }

    m_usageCounters.numDrawCalls[callType]++;

    float boundingRectWidth = static_cast<float>(width);
    float boundingRectHeight = static_cast<float>(height);
    float boundingRectArea = boundingRectWidth * boundingRectHeight;
    float boundingRectPerimeter = (2.0 * boundingRectWidth) + (2.0 * boundingRectHeight);

    if (callType == FillText
        || callType == FillPath
        || callType == StrokeText
        || callType == StrokePath
        || callType == FillRect
        || callType == StrokeRect) {

        SkPath skPath;
        if (path2d) {
            skPath = path2d->path().getSkPath();
        } else {
            skPath = m_path.getSkPath();
        }


        if (!(callType == FillRect || callType == StrokeRect || callType == DrawVectorImage || callType == DrawBitmapImage)) {
            // The correct width and height were not passed as parameters
            const SkRect& boundingRect = skPath.getBounds();
            boundingRectWidth = static_cast<float>(std::abs(boundingRect.width()));
            boundingRectHeight = static_cast<float>(std::abs(boundingRect.height()));
            boundingRectArea = boundingRectWidth * boundingRectHeight;
            boundingRectPerimeter = 2.0 * boundingRectWidth + 2.0 * boundingRectHeight;
        }

        if (callType == FillPath && skPath.getConvexity() != SkPath::kConvex_Convexity) {
            m_usageCounters.numNonConvexFillPathCalls++;
            m_usageCounters.nonConvexFillPathArea += boundingRectArea;
        }

        m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectPerimeter;
        m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea;

        CanvasStyle* canvasStyle;
        if (callType == FillText || callType == FillPath || callType == FillRect) {
            canvasStyle = state().fillStyle();
        } else {
            canvasStyle = state().strokeStyle();
        }

        CanvasGradient* gradient = canvasStyle->getCanvasGradient();
        if (gradient) {

            if (gradient->getGradient()->isRadial()) {
                m_usageCounters.numRadialGradients++;
                m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::RadialGradientFillType] += boundingRectArea;
            } else {
                m_usageCounters.numLinearGradients++;
                m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType] += boundingRectArea;
            }
        } else if (canvasStyle->getCanvasPattern()) {
            m_usageCounters.numPatterns++;
            m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::PatternFillType] += boundingRectArea;
        } else {
            m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::ColorFillType] += boundingRectArea;
        }
    }

    if (callType == DrawVectorImage || callType == DrawBitmapImage) {
        m_usageCounters.boundingBoxPerimeterDrawCalls[callType] += boundingRectPerimeter;
        m_usageCounters.boundingBoxAreaDrawCalls[callType] += boundingRectArea;
    }

    if (callType == FillText
        || callType == FillPath
        || callType == StrokeText
        || callType == StrokePath
        || callType == FillRect
        || callType == StrokeRect
        || callType == DrawVectorImage
        || callType == DrawBitmapImage) {
        if (state().shadowBlur() > 0.0 && SkColorGetA(state().shadowColor()) > 0) {
            m_usageCounters.numBlurredShadows++;
            m_usageCounters.boundingBoxAreaTimesShadowBlurSquared += boundingRectArea * state().shadowBlur() * state().shadowBlur();
            m_usageCounters.boundingBoxPerimeterTimesShadowBlurSquared += boundingRectPerimeter * state().shadowBlur() * state().shadowBlur();
        }
    }

    if (state().hasComplexClip()) {
        m_usageCounters.numDrawWithComplexClips++;
    }

    if (stateHasFilter()) {
        m_usageCounters.numFilters++;
    }
}

const BaseRenderingContext2D::UsageCounters& BaseRenderingContext2D::getUsage()
{
    return m_usageCounters;
}

DEFINE_TRACE(BaseRenderingContext2D)
{
    visitor->trace(m_stateStack);
}

BaseRenderingContext2D::UsageCounters::UsageCounters() :
    numDrawCalls {0, 0, 0, 0, 0, 0, 0},
    boundingBoxPerimeterDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
    boundingBoxAreaDrawCalls {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
    boundingBoxAreaFillType {0.0f, 0.0f, 0.0f, 0.0f},
    numNonConvexFillPathCalls(0),
    nonConvexFillPathArea(0.0f),
    numRadialGradients(0),
    numLinearGradients(0),
    numPatterns(0),
    numDrawWithComplexClips(0),
    numBlurredShadows(0),
    boundingBoxAreaTimesShadowBlurSquared(0.0f),
    boundingBoxPerimeterTimesShadowBlurSquared(0.0f),
    numFilters(0),
    numGetImageDataCalls(0),
    areaGetImageDataCalls(0.0),
    numPutImageDataCalls(0),
    areaPutImageDataCalls(0.0),
    numClearRectCalls(0),
    numDrawFocusCalls(0),
    numFramesSinceReset(0) {}


float BaseRenderingContext2D::estimateRenderingCost(ExpensiveCanvasHeuristicParameters::RenderingModeCostIndex index) const
{
    float basicCostOfDrawCalls =
        ExpensiveCanvasHeuristicParameters::FillRectFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillRect] +
        ExpensiveCanvasHeuristicParameters::FillConvexPathFixedCost[index] * (m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.numNonConvexFillPathCalls) +
        ExpensiveCanvasHeuristicParameters::FillNonConvexPathFixedCost[index] * m_usageCounters.numNonConvexFillPathCalls +
        ExpensiveCanvasHeuristicParameters::FillTextFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::FillText] +

        ExpensiveCanvasHeuristicParameters::StrokeRectFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokeRect] +
        ExpensiveCanvasHeuristicParameters::StrokePathFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokePath] +
        ExpensiveCanvasHeuristicParameters::StrokeTextFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::StrokeText] +

        ExpensiveCanvasHeuristicParameters::FillRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillRect] +
        ExpensiveCanvasHeuristicParameters::FillConvexPathVariableCostPerArea[index] * (m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillPath] - m_usageCounters.nonConvexFillPathArea) +
        ExpensiveCanvasHeuristicParameters::FillNonConvexPathVariableCostPerArea[index] * m_usageCounters.nonConvexFillPathArea +
        ExpensiveCanvasHeuristicParameters::FillTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::FillText] +

        ExpensiveCanvasHeuristicParameters::StrokeRectVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeRect] +
        ExpensiveCanvasHeuristicParameters::StrokePathVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokePath] +
        ExpensiveCanvasHeuristicParameters::StrokeTextVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::StrokeText] +

        ExpensiveCanvasHeuristicParameters::PutImageDataFixedCost[index] * m_usageCounters.numPutImageDataCalls +
        ExpensiveCanvasHeuristicParameters::PutImageDataVariableCostPerArea[index] * m_usageCounters.areaPutImageDataCalls +

        ExpensiveCanvasHeuristicParameters::DrawSVGImageFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::DrawVectorImage] +
        ExpensiveCanvasHeuristicParameters::DrawPNGImageFixedCost[index] * m_usageCounters.numDrawCalls[BaseRenderingContext2D::DrawBitmapImage] +

        ExpensiveCanvasHeuristicParameters::DrawSVGImageVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawVectorImage] +
        ExpensiveCanvasHeuristicParameters::DrawPNGImageVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaDrawCalls[BaseRenderingContext2D::DrawBitmapImage];

    float fillTypeAdjustment =
        ExpensiveCanvasHeuristicParameters::PatternFillTypeFixedCost[index] * m_usageCounters.numPatterns +
        ExpensiveCanvasHeuristicParameters::LinearGradientFillTypeFixedCost[index] * m_usageCounters.numLinearGradients +
        ExpensiveCanvasHeuristicParameters::RadialGradientFillTypeFixedCost[index] * m_usageCounters.numRadialGradients +

        ExpensiveCanvasHeuristicParameters::PatternFillTypeVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::PatternFillType] +
        ExpensiveCanvasHeuristicParameters::LinearGradientFillVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::LinearGradientFillType] +
        ExpensiveCanvasHeuristicParameters::RadialGradientFillVariableCostPerArea[index] * m_usageCounters.boundingBoxAreaFillType[BaseRenderingContext2D::RadialGradientFillType];

    float shadowAdjustment =
        ExpensiveCanvasHeuristicParameters::ShadowFixedCost[index] * m_usageCounters.numBlurredShadows +
        ExpensiveCanvasHeuristicParameters::ShadowVariableCostPerAreaTimesShadowBlurSquared[index] * m_usageCounters.boundingBoxAreaTimesShadowBlurSquared;

    return basicCostOfDrawCalls + fillTypeAdjustment + shadowAdjustment;
}

} // namespace blink
