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

Side by Side Diff: Source/modules/canvas2d/CanvasRenderingContext2D.cpp

Issue 1297663002: Eliminate deferral overhead with canvas to canvas draws (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
10 * 10 *
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 c->saveLayer(nullptr, &compositePaint); 872 c->saveLayer(nullptr, &compositePaint);
873 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType); 873 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType);
874 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 874 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
875 c->setMatrix(ctm); 875 c->setMatrix(ctm);
876 drawFunc(c, &foregroundPaint); 876 drawFunc(c, &foregroundPaint);
877 c->restore(); 877 c->restore();
878 c->setMatrix(ctm); 878 c->setMatrix(ctm);
879 } 879 }
880 880
881 template<typename DrawFunc, typename ContainsFunc> 881 template<typename DrawFunc, typename ContainsFunc>
882 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, CanvasDeferralMode deferralMode, const SkRect& bounds, C anvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState ::ImageType imageType) 882 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType)
883 { 883 {
884 if (!state().isTransformInvertible()) 884 if (!state().isTransformInvertible())
885 return false; 885 return false;
886 886
887 SkIRect clipBounds; 887 SkIRect clipBounds;
888 // Deliberately not using 'deferralMode' in the call to drawingCanvas below because
889 // a) The call does not write anything so we do not care about the write mod e here
890 // b) We want to avoid flushing before the call to checkOverdraw (below), ot herwise
891 // we could be supressing an overdraw optimization.
892 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds)) 888 if (!drawingCanvas()->getClipDeviceBounds(&clipBounds))
893 return false; 889 return false;
894 890
895 // If gradient size is zero, then paint nothing. 891 // If gradient size is zero, then paint nothing.
896 CanvasStyle* style = state().style(paintType); 892 CanvasStyle* style = state().style(paintType);
897 if (style) { 893 if (style) {
898 CanvasGradient* gradient = style->canvasGradient(); 894 CanvasGradient* gradient = style->canvasGradient();
899 if (gradient && gradient->gradient()->isZeroSize()) 895 if (gradient && gradient->gradient()->isZeroSize())
900 return false; 896 return false;
901 } 897 }
902 898
903 if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilte r()) { 899 if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilte r()) {
904 compositedDraw(drawFunc, drawingCanvas(deferralMode), paintType, imageTy pe); 900 compositedDraw(drawFunc, drawingCanvas(), paintType, imageType);
905 didDraw(clipBounds); 901 didDraw(clipBounds);
906 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { 902 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
907 clearCanvas(); // takes care of checkOvewrdraw() 903 clearCanvas(); // takes care of checkOvewrdraw()
908 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType); 904 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType);
909 drawFunc(drawingCanvas(deferralMode), paint); 905 drawFunc(drawingCanvas(), paint);
910 didDraw(clipBounds); 906 didDraw(clipBounds);
911 } else { 907 } else {
912 SkIRect dirtyRect; 908 SkIRect dirtyRect;
913 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { 909 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
914 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType); 910 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType);
915 if (paintType != CanvasRenderingContext2DState::StrokePaintType && d rawCoversClipBounds(clipBounds)) 911 if (paintType != CanvasRenderingContext2DState::StrokePaintType && d rawCoversClipBounds(clipBounds))
916 checkOverdraw(bounds, paint, imageType, ClipFill); 912 checkOverdraw(bounds, paint, imageType, ClipFill);
917 drawFunc(drawingCanvas(deferralMode), paint); 913 drawFunc(drawingCanvas(), paint);
918 didDraw(dirtyRect); 914 didDraw(dirtyRect);
919 } 915 }
920 } 916 }
921 return true; 917 return true;
922 } 918 }
923 919
924 static bool isPathExpensive(const Path& path) 920 static bool isPathExpensive(const Path& path)
925 { 921 {
926 const SkPath& skPath = path.skPath(); 922 const SkPath& skPath = path.skPath();
927 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive && !skPath. isConvex()) 923 if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive && !skPath. isConvex())
(...skipping 21 matching lines...) Expand all
949 return; 945 return;
950 946
951 if (draw( 947 if (draw(
952 [&skPath, this](SkCanvas* c, const SkPaint* paint) // draw lambda 948 [&skPath, this](SkCanvas* c, const SkPaint* paint) // draw lambda
953 { 949 {
954 c->drawPath(skPath, *paint); 950 c->drawPath(skPath, *paint);
955 }, 951 },
956 [](const SkIRect& rect) // overdraw test lambda 952 [](const SkIRect& rect) // overdraw test lambda
957 { 953 {
958 return false; 954 return false;
959 }, AllowDeferredCanvas, bounds, paintType)) { 955 }, bounds, paintType)) {
960 if (isPathExpensive(path)) { 956 if (isPathExpensive(path)) {
961 ImageBuffer* buffer = canvas()->buffer(); 957 ImageBuffer* buffer = canvas()->buffer();
962 if (buffer) 958 if (buffer)
963 buffer->setHasExpensiveOp(); 959 buffer->setHasExpensiveOp();
964 } 960 }
965 } 961 }
966 } 962 }
967 963
968 static SkPath::FillType parseWinding(const String& windingRuleString) 964 static SkPath::FillType parseWinding(const String& windingRuleString)
969 { 965 {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 1002
1007 SkRect rect = SkRect::MakeXYWH(x, y, width, height); 1003 SkRect rect = SkRect::MakeXYWH(x, y, width, height);
1008 draw( 1004 draw(
1009 [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda 1005 [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda
1010 { 1006 {
1011 c->drawRect(rect, *paint); 1007 c->drawRect(rect, *paint);
1012 }, 1008 },
1013 [&rect, this](const SkIRect& clipBounds) // overdraw test lambda 1009 [&rect, this](const SkIRect& clipBounds) // overdraw test lambda
1014 { 1010 {
1015 return rectContainsTransformedRect(rect, clipBounds); 1011 return rectContainsTransformedRect(rect, clipBounds);
1016 }, AllowDeferredCanvas, rect, CanvasRenderingContext2DState::FillPaintTy pe); 1012 }, rect, CanvasRenderingContext2DState::FillPaintType);
1017 } 1013 }
1018 1014
1019 static void strokeRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const Sk Paint* paint) 1015 static void strokeRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const Sk Paint* paint)
1020 { 1016 {
1021 ASSERT(paint->getStyle() == SkPaint::kStroke_Style); 1017 ASSERT(paint->getStyle() == SkPaint::kStroke_Style);
1022 if ((rect.width() > 0) != (rect.height() > 0)) { 1018 if ((rect.width() > 0) != (rect.height() > 0)) {
1023 // When stroking, we must skip the zero-dimension segments 1019 // When stroking, we must skip the zero-dimension segments
1024 SkPath path; 1020 SkPath path;
1025 path.moveTo(rect.x(), rect.y()); 1021 path.moveTo(rect.x(), rect.y());
1026 path.lineTo(rect.maxX(), rect.maxY()); 1022 path.lineTo(rect.maxX(), rect.maxY());
(...skipping 16 matching lines...) Expand all
1043 FloatRect bounds = rect; 1039 FloatRect bounds = rect;
1044 inflateStrokeRect(bounds); 1040 inflateStrokeRect(bounds);
1045 draw( 1041 draw(
1046 [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda 1042 [&rect, this](SkCanvas* c, const SkPaint* paint) // draw lambda
1047 { 1043 {
1048 strokeRectOnCanvas(rect, c, paint); 1044 strokeRectOnCanvas(rect, c, paint);
1049 }, 1045 },
1050 [](const SkIRect& clipBounds) // overdraw test lambda 1046 [](const SkIRect& clipBounds) // overdraw test lambda
1051 { 1047 {
1052 return false; 1048 return false;
1053 }, AllowDeferredCanvas, bounds, CanvasRenderingContext2DState::StrokePai ntType); 1049 }, bounds, CanvasRenderingContext2DState::StrokePaintType);
1054 } 1050 }
1055 1051
1056 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString) 1052 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString)
1057 { 1053 {
1058 SkCanvas* c = drawingCanvas(); 1054 SkCanvas* c = drawingCanvas();
1059 if (!c) { 1055 if (!c) {
1060 return; 1056 return;
1061 } 1057 }
1062 if (!state().isTransformInvertible()) { 1058 if (!state().isTransformInvertible()) {
1063 return; 1059 return;
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh)); 1381 FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
1386 FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh)); 1382 FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
1387 1383
1388 clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->elementSize()), &s rcRect, &dstRect); 1384 clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->elementSize()), &s rcRect, &dstRect);
1389 1385
1390 imageSource->adjustDrawRects(&srcRect, &dstRect); 1386 imageSource->adjustDrawRects(&srcRect, &dstRect);
1391 1387
1392 if (srcRect.isEmpty()) 1388 if (srcRect.isEmpty())
1393 return; 1389 return;
1394 1390
1395 CanvasDeferralMode deferralMode = imageSource->isVideoElement() ? ForceImmed iateCanvas : AllowDeferredCanvas; 1391 // FIXME: crbug.com/447218
Stephen White 2015/08/14 15:10:48 Nit: this bug is marked as fixed. Also, it's about
1392 // We make the destination canvas fall out of display list mode by forcing
1393 // immediate rendering. This is to prevent run-away memory consumption cause d by SkSurface
1394 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the
1395 // presentation frame rate of the destination canvas.
1396 if (imageSource->isVideoElement() || imageSource->isCanvasElement())
1397 canvas()->disableDeferral();
1396 1398
1397 validateStateStack(); 1399 validateStateStack();
1398 1400
1399 draw( 1401 draw(
1400 [this, &imageSource, &image, &srcRect, dstRect](SkCanvas* c, const SkPai nt* paint) // draw lambda 1402 [this, &imageSource, &image, &srcRect, dstRect](SkCanvas* c, const SkPai nt* paint) // draw lambda
1401 { 1403 {
1402 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, pai nt); 1404 drawImageInternal(c, imageSource, image.get(), srcRect, dstRect, pai nt);
1403 }, 1405 },
1404 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda 1406 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda
1405 { 1407 {
1406 return rectContainsTransformedRect(dstRect, clipBounds); 1408 return rectContainsTransformedRect(dstRect, clipBounds);
1407 }, deferralMode, dstRect, CanvasRenderingContext2DState::ImagePaintType, 1409 }, dstRect, CanvasRenderingContext2DState::ImagePaintType,
1408 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : C anvasRenderingContext2DState::NonOpaqueImage); 1410 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : C anvasRenderingContext2DState::NonOpaqueImage);
1409 1411
1410 validateStateStack(); 1412 validateStateStack();
1411 1413
1412 bool isExpensive = false; 1414 bool isExpensive = false;
1413 1415
1414 if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && image && image->isSVGImage()) 1416 if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && image && image->isSVGImage())
1415 isExpensive = true; 1417 isExpensive = true;
1416 1418
1417 if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters:: ExpensiveImageSizeRatio) 1419 if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters:: ExpensiveImageSizeRatio)
1418 isExpensive = true; 1420 isExpensive = true;
1419 1421
1420 if (isExpensive) { 1422 if (isExpensive) {
1421 ImageBuffer* buffer = canvas()->buffer(); 1423 ImageBuffer* buffer = canvas()->buffer();
1422 if (buffer) 1424 if (buffer)
1423 buffer->setHasExpensiveOp(); 1425 buffer->setHasExpensiveOp();
1424 } 1426 }
1425 1427
1426 if (imageSource->isCanvasElement()) { 1428 if (imageSource->isCanvasElement() && static_cast<HTMLCanvasElement*>(imageS ource)->is3D()) {
1427 if (static_cast<HTMLCanvasElement*>(imageSource)->is3D()) { 1429 // WebGL to 2D canvas: must flush graphics context to prevent a race
1428 // WebGL to 2D canvas: must flush graphics context to prevent a race 1430 // FIXME: crbug.com/516331 Fix the underlying synchronization issue so t his flush can be eliminated.
1429 // FIXME: crbug.com/516331 Fix the underlying synchronization issue so this flush can be eliminated. 1431 canvas()->buffer()->flushGpu();
1430 canvas()->buffer()->flushGpu();
1431 } else {
1432 // FIXME: crbug.com/447218
1433 // We make the destination canvas fall out of display list mode by c alling
1434 // flush. This is to prevent run-away memory consumption caused by S kSurface
1435 // copyOnWrite when the source canvas is animated and consumed at a rate higher than the
1436 // presentation frame rate of the destination canvas.
1437 canvas()->buffer()->flush();
1438 }
1439 } 1432 }
1440 1433
1441 if (canvas()->originClean() && wouldTaintOrigin(imageSource)) 1434 if (canvas()->originClean() && wouldTaintOrigin(imageSource))
1442 canvas()->setOriginTainted(); 1435 canvas()->setOriginTainted();
1443 } 1436 }
1444 1437
1445 void CanvasRenderingContext2D::clearCanvas() 1438 void CanvasRenderingContext2D::clearCanvas()
1446 { 1439 {
1447 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); 1440 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
1448 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, ClipFil l); 1441 checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, ClipFil l);
1449 if (drawingCanvas()) 1442 SkCanvas* c = drawingCanvas();
1450 drawingCanvas()->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK) ; 1443 if (c)
1444 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
1451 } 1445 }
1452 1446
1453 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const SkIRect& transformedRect) const 1447 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const SkIRect& transformedRect) const
1454 { 1448 {
1455 FloatQuad quad(rect); 1449 FloatQuad quad(rect);
1456 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y() , transformedRect.width(), transformedRect.height())); 1450 FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y() , transformedRect.width(), transformedRect.height()));
1457 return state().transform().mapQuad(quad).containsQuad(transformedQuad); 1451 return state().transform().mapQuad(quad).containsQuad(transformedQuad);
1458 } 1452 }
1459 1453
1460 CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y 0, float x1, float y1) 1454 CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y 0, float x1, float y1)
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 1540
1547 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && state( ).shouldDrawShadows() && state().shadowBlur() > 0) { 1541 if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && state( ).shouldDrawShadows() && state().shadowBlur() > 0) {
1548 ImageBuffer* buffer = canvas()->buffer(); 1542 ImageBuffer* buffer = canvas()->buffer();
1549 if (buffer) 1543 if (buffer)
1550 buffer->setHasExpensiveOp(); 1544 buffer->setHasExpensiveOp();
1551 } 1545 }
1552 1546
1553 canvas()->didDraw(SkRect::Make(dirtyRect)); 1547 canvas()->didDraw(SkRect::Make(dirtyRect));
1554 } 1548 }
1555 1549
1556 SkCanvas* CanvasRenderingContext2D::drawingCanvas(CanvasDeferralMode deferralMod e) const 1550 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const
1557 { 1551 {
1558 if (isContextLost()) 1552 if (isContextLost())
1559 return nullptr; 1553 return nullptr;
1560 return deferralMode == ForceImmediateCanvas ? canvas()->immediateDrawingCanv as() : canvas()->drawingCanvas(); 1554 return canvas()->drawingCanvas();
1561 } 1555 }
1562 1556
1563 ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const 1557 ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const
1564 { 1558 {
1565 return ImageData::create(imageData->size()); 1559 return ImageData::create(imageData->size());
1566 } 1560 }
1567 1561
1568 ImageData* CanvasRenderingContext2D::createImageData(float sw, float sh, Excepti onState& exceptionState) const 1562 ImageData* CanvasRenderingContext2D::createImageData(float sw, float sh, Excepti onState& exceptionState) const
1569 { 1563 {
1570 if (!sw || !sh) { 1564 if (!sw || !sh) {
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 2007
2014 draw( 2008 draw(
2015 [&font, this, &textRunPaintInfo, &location](SkCanvas* c, const SkPaint* paint) // draw lambda 2009 [&font, this, &textRunPaintInfo, &location](SkCanvas* c, const SkPaint* paint) // draw lambda
2016 { 2010 {
2017 font.drawBidiText(c, textRunPaintInfo, location, Font::UseFallbackIf FontNotReady, cDeviceScaleFactor, *paint); 2011 font.drawBidiText(c, textRunPaintInfo, location, Font::UseFallbackIf FontNotReady, cDeviceScaleFactor, *paint);
2018 }, 2012 },
2019 [](const SkIRect& rect) // overdraw test lambda 2013 [](const SkIRect& rect) // overdraw test lambda
2020 { 2014 {
2021 return false; 2015 return false;
2022 }, 2016 },
2023 AllowDeferredCanvas, textRunPaintInfo.bounds, paintType); 2017 textRunPaintInfo.bounds, paintType);
2024 } 2018 }
2025 2019
2026 void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const 2020 void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
2027 { 2021 {
2028 // Fast approximation of the stroke's bounding rect. 2022 // Fast approximation of the stroke's bounding rect.
2029 // This yields a slightly oversized rect but is very fast 2023 // This yields a slightly oversized rect but is very fast
2030 // compared to Path::strokeBoundingRect(). 2024 // compared to Path::strokeBoundingRect().
2031 static const float root2 = sqrtf(2); 2025 static const float root2 = sqrtf(2);
2032 float delta = state().lineWidth() / 2; 2026 float delta = state().lineWidth() / 2;
2033 if (state().lineJoin() == MiterJoin) 2027 if (state().lineJoin() == MiterJoin)
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) 2311 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage)
2318 return; 2312 return;
2319 if (alpha < 0xFF) 2313 if (alpha < 0xFF)
2320 return; 2314 return;
2321 } 2315 }
2322 2316
2323 canvas()->buffer()->willOverwriteCanvas(); 2317 canvas()->buffer()->willOverwriteCanvas();
2324 } 2318 }
2325 2319
2326 } // namespace blink 2320 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/canvas2d/CanvasRenderingContext2D.h ('k') | Source/platform/graphics/Canvas2DImageBufferSurface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698