| Index: Source/modules/canvas2d/CanvasRenderingContext2D.cpp
|
| diff --git a/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
|
| index 022cbf97d6805244fe96430eb2c43c8ebd7b98c7..41d48fe8be8d093508a6b6f92642f749708b670b 100644
|
| --- a/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
|
| +++ b/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
|
| @@ -879,16 +879,12 @@ void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, SkCanvas
|
| }
|
|
|
| template<typename DrawFunc, typename ContainsFunc>
|
| -bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc& drawCoversClipBounds, CanvasDeferralMode deferralMode, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
|
| +bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc& drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
|
| {
|
| if (!state().isTransformInvertible())
|
| return false;
|
|
|
| SkIRect clipBounds;
|
| - // Deliberately not using 'deferralMode' in the call to drawingCanvas below because
|
| - // a) The call does not write anything so we do not care about the write mode here
|
| - // b) We want to avoid flushing before the call to checkOverdraw (below), otherwise
|
| - // we could be supressing an overdraw optimization.
|
| if (!drawingCanvas()->getClipDeviceBounds(&clipBounds))
|
| return false;
|
|
|
| @@ -901,12 +897,12 @@ bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc
|
| }
|
|
|
| if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilter()) {
|
| - compositedDraw(drawFunc, drawingCanvas(deferralMode), paintType, imageType);
|
| + compositedDraw(drawFunc, drawingCanvas(), paintType, imageType);
|
| didDraw(clipBounds);
|
| } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
|
| clearCanvas(); // takes care of checkOvewrdraw()
|
| const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, imageType);
|
| - drawFunc(drawingCanvas(deferralMode), paint);
|
| + drawFunc(drawingCanvas(), paint);
|
| didDraw(clipBounds);
|
| } else {
|
| SkIRect dirtyRect;
|
| @@ -914,7 +910,7 @@ bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc
|
| const SkPaint* paint = state().getPaint(paintType, DrawShadowAndForeground, imageType);
|
| if (paintType != CanvasRenderingContext2DState::StrokePaintType && drawCoversClipBounds(clipBounds))
|
| checkOverdraw(bounds, paint, imageType, ClipFill);
|
| - drawFunc(drawingCanvas(deferralMode), paint);
|
| + drawFunc(drawingCanvas(), paint);
|
| didDraw(dirtyRect);
|
| }
|
| }
|
| @@ -956,7 +952,7 @@ void CanvasRenderingContext2D::drawPathInternal(const Path& path, CanvasRenderin
|
| [](const SkIRect& rect) // overdraw test lambda
|
| {
|
| return false;
|
| - }, AllowDeferredCanvas, bounds, paintType)) {
|
| + }, bounds, paintType)) {
|
| if (isPathExpensive(path)) {
|
| ImageBuffer* buffer = canvas()->buffer();
|
| if (buffer)
|
| @@ -1013,7 +1009,7 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
|
| [&rect, this](const SkIRect& clipBounds) // overdraw test lambda
|
| {
|
| return rectContainsTransformedRect(rect, clipBounds);
|
| - }, AllowDeferredCanvas, rect, CanvasRenderingContext2DState::FillPaintType);
|
| + }, rect, CanvasRenderingContext2DState::FillPaintType);
|
| }
|
|
|
| static void strokeRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const SkPaint* paint)
|
| @@ -1050,7 +1046,7 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
|
| [](const SkIRect& clipBounds) // overdraw test lambda
|
| {
|
| return false;
|
| - }, AllowDeferredCanvas, bounds, CanvasRenderingContext2DState::StrokePaintType);
|
| + }, bounds, CanvasRenderingContext2DState::StrokePaintType);
|
| }
|
|
|
| void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
|
| @@ -1392,7 +1388,13 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
|
| if (srcRect.isEmpty())
|
| return;
|
|
|
| - CanvasDeferralMode deferralMode = imageSource->isVideoElement() ? ForceImmediateCanvas : AllowDeferredCanvas;
|
| + // FIXME: crbug.com/521001
|
| + // We make the destination canvas fall out of display list mode by forcing
|
| + // immediate rendering. This is to prevent run-away memory consumption caused by SkSurface
|
| + // copyOnWrite when the source canvas is animated and consumed at a rate higher than the
|
| + // presentation frame rate of the destination canvas.
|
| + if (imageSource->isVideoElement() || imageSource->isCanvasElement())
|
| + canvas()->disableDeferral();
|
|
|
| validateStateStack();
|
|
|
| @@ -1404,7 +1406,7 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
|
| [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda
|
| {
|
| return rectContainsTransformedRect(dstRect, clipBounds);
|
| - }, deferralMode, dstRect, CanvasRenderingContext2DState::ImagePaintType,
|
| + }, dstRect, CanvasRenderingContext2DState::ImagePaintType,
|
| imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : CanvasRenderingContext2DState::NonOpaqueImage);
|
|
|
| validateStateStack();
|
| @@ -1423,19 +1425,10 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
|
| buffer->setHasExpensiveOp();
|
| }
|
|
|
| - if (imageSource->isCanvasElement()) {
|
| - if (static_cast<HTMLCanvasElement*>(imageSource)->is3D()) {
|
| - // WebGL to 2D canvas: must flush graphics context to prevent a race
|
| - // FIXME: crbug.com/516331 Fix the underlying synchronization issue so this flush can be eliminated.
|
| - canvas()->buffer()->flushGpu();
|
| - } else {
|
| - // FIXME: crbug.com/447218
|
| - // We make the destination canvas fall out of display list mode by calling
|
| - // flush. This is to prevent run-away memory consumption caused by SkSurface
|
| - // copyOnWrite when the source canvas is animated and consumed at a rate higher than the
|
| - // presentation frame rate of the destination canvas.
|
| - canvas()->buffer()->flush();
|
| - }
|
| + if (imageSource->isCanvasElement() && static_cast<HTMLCanvasElement*>(imageSource)->is3D()) {
|
| + // WebGL to 2D canvas: must flush graphics context to prevent a race
|
| + // FIXME: crbug.com/516331 Fix the underlying synchronization issue so this flush can be eliminated.
|
| + canvas()->buffer()->flushGpu();
|
| }
|
|
|
| if (canvas()->originClean() && wouldTaintOrigin(imageSource))
|
| @@ -1446,8 +1439,9 @@ void CanvasRenderingContext2D::clearCanvas()
|
| {
|
| FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
|
| checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, ClipFill);
|
| - if (drawingCanvas())
|
| - drawingCanvas()->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
|
| + SkCanvas* c = drawingCanvas();
|
| + if (c)
|
| + c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
|
| }
|
|
|
| bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect, const SkIRect& transformedRect) const
|
| @@ -1553,11 +1547,11 @@ void CanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect)
|
| canvas()->didDraw(SkRect::Make(dirtyRect));
|
| }
|
|
|
| -SkCanvas* CanvasRenderingContext2D::drawingCanvas(CanvasDeferralMode deferralMode) const
|
| +SkCanvas* CanvasRenderingContext2D::drawingCanvas() const
|
| {
|
| if (isContextLost())
|
| return nullptr;
|
| - return deferralMode == ForceImmediateCanvas ? canvas()->immediateDrawingCanvas() : canvas()->drawingCanvas();
|
| + return canvas()->drawingCanvas();
|
| }
|
|
|
| ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const
|
| @@ -2020,7 +2014,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
|
| {
|
| return false;
|
| },
|
| - AllowDeferredCanvas, textRunPaintInfo.bounds, paintType);
|
| + textRunPaintInfo.bounds, paintType);
|
| }
|
|
|
| void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
|
|
|