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

Side by Side Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 907453003: Move overdraw tracking code from GraphicsContext to CanvasRenderingContext2D (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: adding missing test file Created 5 years, 10 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 , m_globalComposite(SkXfermode::kSrcOver_Mode) 276 , m_globalComposite(SkXfermode::kSrcOver_Mode)
277 , m_invertibleCTM(true) 277 , m_invertibleCTM(true)
278 , m_lineDashOffset(0) 278 , m_lineDashOffset(0)
279 , m_imageSmoothingEnabled(true) 279 , m_imageSmoothingEnabled(true)
280 , m_textAlign(StartTextAlign) 280 , m_textAlign(StartTextAlign)
281 , m_textBaseline(AlphabeticTextBaseline) 281 , m_textBaseline(AlphabeticTextBaseline)
282 , m_direction(DirectionInherit) 282 , m_direction(DirectionInherit)
283 , m_unparsedFont(defaultFont) 283 , m_unparsedFont(defaultFont)
284 , m_realizedFont(false) 284 , m_realizedFont(false)
285 , m_hasClip(false) 285 , m_hasClip(false)
286 , m_hasComplexClip(false)
286 { 287 {
287 } 288 }
288 289
289 CanvasRenderingContext2D::State::State(const State& other, ClipListCopyMode mode ) 290 CanvasRenderingContext2D::State::State(const State& other, ClipListCopyMode mode )
290 : CSSFontSelectorClient() 291 : CSSFontSelectorClient()
291 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) 292 , m_unrealizedSaveCount(other.m_unrealizedSaveCount)
292 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) 293 , m_unparsedStrokeColor(other.m_unparsedStrokeColor)
293 , m_unparsedFillColor(other.m_unparsedFillColor) 294 , m_unparsedFillColor(other.m_unparsedFillColor)
294 , m_strokeStyle(other.m_strokeStyle) 295 , m_strokeStyle(other.m_strokeStyle)
295 , m_fillStyle(other.m_fillStyle) 296 , m_fillStyle(other.m_fillStyle)
(...skipping 10 matching lines...) Expand all
306 , m_invertibleCTM(other.m_invertibleCTM) 307 , m_invertibleCTM(other.m_invertibleCTM)
307 , m_lineDashOffset(other.m_lineDashOffset) 308 , m_lineDashOffset(other.m_lineDashOffset)
308 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) 309 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled)
309 , m_textAlign(other.m_textAlign) 310 , m_textAlign(other.m_textAlign)
310 , m_textBaseline(other.m_textBaseline) 311 , m_textBaseline(other.m_textBaseline)
311 , m_direction(other.m_direction) 312 , m_direction(other.m_direction)
312 , m_unparsedFont(other.m_unparsedFont) 313 , m_unparsedFont(other.m_unparsedFont)
313 , m_font(other.m_font) 314 , m_font(other.m_font)
314 , m_realizedFont(other.m_realizedFont) 315 , m_realizedFont(other.m_realizedFont)
315 , m_hasClip(other.m_hasClip) 316 , m_hasClip(other.m_hasClip)
317 , m_hasComplexClip(other.m_hasComplexClip)
316 { 318 {
317 if (mode == CopyClipList) { 319 if (mode == CopyClipList) {
318 m_clipList = other.m_clipList; 320 m_clipList = other.m_clipList;
319 } 321 }
320 if (m_realizedFont) 322 if (m_realizedFont)
321 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); 323 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this);
322 } 324 }
323 325
324 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other) 326 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other)
325 { 327 {
(...skipping 22 matching lines...) Expand all
348 m_transform = other.m_transform; 350 m_transform = other.m_transform;
349 m_invertibleCTM = other.m_invertibleCTM; 351 m_invertibleCTM = other.m_invertibleCTM;
350 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; 352 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled;
351 m_textAlign = other.m_textAlign; 353 m_textAlign = other.m_textAlign;
352 m_textBaseline = other.m_textBaseline; 354 m_textBaseline = other.m_textBaseline;
353 m_direction = other.m_direction; 355 m_direction = other.m_direction;
354 m_unparsedFont = other.m_unparsedFont; 356 m_unparsedFont = other.m_unparsedFont;
355 m_font = other.m_font; 357 m_font = other.m_font;
356 m_realizedFont = other.m_realizedFont; 358 m_realizedFont = other.m_realizedFont;
357 m_hasClip = other.m_hasClip; 359 m_hasClip = other.m_hasClip;
360 m_hasComplexClip = other.m_hasComplexClip;
358 m_clipList = other.m_clipList; 361 m_clipList = other.m_clipList;
359 362
360 if (m_realizedFont) 363 if (m_realizedFont)
361 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); 364 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this);
362 365
363 return *this; 366 return *this;
364 } 367 }
365 368
366 CanvasRenderingContext2D::State::~State() 369 CanvasRenderingContext2D::State::~State()
367 { 370 {
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 1118
1116 SkPath skPath = path.skPath(); 1119 SkPath skPath = path.skPath();
1117 skPath.setFillType(parseWinding(windingRuleString)); 1120 skPath.setFillType(parseWinding(windingRuleString));
1118 ImageBuffer* buffer = canvas()->buffer(); 1121 ImageBuffer* buffer = canvas()->buffer();
1119 if (buffer && buffer->needsClipTracking()) { 1122 if (buffer && buffer->needsClipTracking()) {
1120 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform)); 1123 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform));
1121 } 1124 }
1122 1125
1123 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed); 1126 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed);
1124 if (!skPath.isRect(0)) 1127 if (!skPath.isRect(0))
1125 drawingContext()->setHasComplexClip(); 1128 modifiableState().m_hasComplexClip = true;
1126 modifiableState().m_hasClip = true; 1129 modifiableState().m_hasClip = true;
1127 } 1130 }
1128 1131
1129 void CanvasRenderingContext2D::clip(const String& windingRuleString) 1132 void CanvasRenderingContext2D::clip(const String& windingRuleString)
1130 { 1133 {
1131 clipInternal(m_path, windingRuleString); 1134 clipInternal(m_path, windingRuleString);
1132 } 1135 }
1133 1136
1134 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) 1137 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring)
1135 { 1138 {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopA lways); 1232 pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopA lways);
1230 1233
1231 // TODO: should implement "inform the user" that the caret and/or 1234 // TODO: should implement "inform the user" that the caret and/or
1232 // selection the specified rectangle of the canvas. See http://crbug.com/357 987 1235 // selection the specified rectangle of the canvas. See http://crbug.com/357 987
1233 } 1236 }
1234 1237
1235 void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he ight) 1238 void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he ight)
1236 { 1239 {
1237 if (!validateRectForCanvas(x, y, width, height)) 1240 if (!validateRectForCanvas(x, y, width, height))
1238 return; 1241 return;
1239 GraphicsContext* context = drawingContext();
1240 if (!context)
1241 return;
1242 if (!state().m_invertibleCTM)
1243 return;
1244 FloatRect rect(x, y, width, height);
1245 1242
1246 FloatRect dirtyRect; 1243 GraphicsContext* c = drawingContext();
1247 if (!computeDirtyRect(rect, &dirtyRect)) 1244 if (!c)
1248 return; 1245 return;
1249 1246
1250 context->clearShadow(); 1247 c->clearShadow();
1251 context->setAlphaAsFloat(1); 1248 c->setAlphaAsFloat(1);
1252 context->setCompositeOperation(SkXfermode::kSrcOver_Mode); 1249 c->setCompositeOperation(SkXfermode::kClear_Mode);
1253 1250
1254 context->clearRect(rect); 1251 fillRect(x, y, width, height);
1255 if (m_hitRegionManager)
1256 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform);
1257 1252
1258 applyShadow(DrawShadowAndForeground); 1253 applyShadow(DrawShadowAndForeground);
1259 context->setAlphaAsFloat(state().m_globalAlpha); 1254 c->setAlphaAsFloat(state().m_globalAlpha);
1260 context->setCompositeOperation(state().m_globalComposite); 1255 c->setCompositeOperation(state().m_globalComposite);
1261 1256
1262 validateStateStack(); 1257 if (m_hitRegionManager) {
1263 didDraw(dirtyRect); 1258 FloatRect rect(x, y, width, height);
1259 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform);
Ken Russell (switch to Gerrit) 2015/02/11 10:11:44 Why was the check removed above of whether the sta
Justin Novosad 2015/02/11 18:59:54 Good catch, my thinking was that we already check
1260 }
dshwang 2015/02/11 08:37:52 why didDraw is removed?
Justin Novosad 2015/02/11 18:59:54 didDraw is taken care of by fillRect now. I'll add
1264 } 1261 }
1265 1262
1266 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. 1263 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e.
1267 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) 1264 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect)
1268 { 1265 {
1269 context->fillRect(rect); 1266 context->fillRect(rect);
1270 } 1267 }
1271 1268
1272 static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect) 1269 static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect)
1273 { 1270 {
(...skipping 16 matching lines...) Expand all
1290 1287
1291 // from the HTML5 Canvas spec: 1288 // from the HTML5 Canvas spec:
1292 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing 1289 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing
1293 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing 1290 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing
1294 Gradient* gradient = c->fillGradient(); 1291 Gradient* gradient = c->fillGradient();
1295 if (gradient && gradient->isZeroSize()) 1292 if (gradient && gradient->isZeroSize())
1296 return; 1293 return;
1297 1294
1298 FloatRect rect(x, y, width, height); 1295 FloatRect rect(x, y, width, height);
1299 if (rectContainsTransformedRect(rect, clipBounds)) { 1296 if (rectContainsTransformedRect(rect, clipBounds)) {
1297 checkOverdraw(rect, &c->fillPaint(), NoImage, ClipFill);
1300 c->fillRect(rect); 1298 c->fillRect(rect);
1301 didDraw(clipBounds); 1299 didDraw(clipBounds);
1302 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { 1300 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
1303 fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect)); 1301 fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect));
1304 didDraw(clipBounds); 1302 didDraw(clipBounds);
1305 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { 1303 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) {
1306 clearCanvas(); 1304 clearCanvas();
1307 c->clearShadow(); 1305 c->clearShadow(); // Takes care of signaling the overdraw
1308 c->fillRect(rect); 1306 c->fillRect(rect);
1309 applyShadow(DrawShadowAndForeground); 1307 applyShadow(DrawShadowAndForeground);
1310 didDraw(clipBounds); 1308 didDraw(clipBounds);
1311 } else { 1309 } else {
1312 FloatRect dirtyRect; 1310 FloatRect dirtyRect;
1313 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { 1311 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) {
1314 c->fillRect(rect); 1312 c->fillRect(rect);
1315 didDraw(dirtyRect); 1313 didDraw(dirtyRect);
1316 } 1314 }
1317 } 1315 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 return value.getAsImageBitmap().get(); 1416 return value.getAsImageBitmap().get();
1419 ASSERT_NOT_REACHED(); 1417 ASSERT_NOT_REACHED();
1420 return nullptr; 1418 return nullptr;
1421 } 1419 }
1422 1420
1423 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, float x, float y, ExceptionState& exceptionState) 1421 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, float x, float y, ExceptionState& exceptionState)
1424 { 1422 {
1425 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); 1423 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
1426 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); 1424 FloatSize sourceRectSize = imageSourceInternal->sourceSize();
1427 FloatSize destRectSize = imageSourceInternal->defaultDestinationSize(); 1425 FloatSize destRectSize = imageSourceInternal->defaultDestinationSize();
1428 drawImageInternal(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceR ectSize.height(), x, y, destRectSize.width(), destRectSize.height(), exceptionSt ate); 1426 drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize. height(), x, y, destRectSize.width(), destRectSize.height(), exceptionState);
1429 } 1427 }
1430 1428
1431 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, 1429 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce,
1432 float x, float y, float width, float height, ExceptionState& exceptionState) 1430 float x, float y, float width, float height, ExceptionState& exceptionState)
1433 { 1431 {
1434 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); 1432 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
1435 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); 1433 FloatSize sourceRectSize = imageSourceInternal->sourceSize();
1436 drawImageInternal(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceR ectSize.height(), x, y, width, height, exceptionState); 1434 drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize. height(), x, y, width, height, exceptionState);
1437 } 1435 }
1438 1436
1439 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, 1437 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce,
1440 float sx, float sy, float sw, float sh, 1438 float sx, float sy, float sw, float sh,
1441 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1439 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1442 { 1440 {
1443 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); 1441 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
1444 drawImageInternal(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, excep tionState); 1442 drawImage(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionStat e);
1445 } 1443 }
1446 1444
1447 static void drawVideo(SkCanvas* c, GraphicsContext* gc, CanvasImageSource* image Source, FloatRect srcRect, FloatRect dstRect) 1445 static void drawVideo(SkCanvas* c, GraphicsContext* gc, CanvasImageSource* image Source, FloatRect srcRect, FloatRect dstRect)
1448 { 1446 {
1449 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource); 1447 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource);
1450 c->save(); 1448 c->save();
1451 c->clipRect(WebCoreFloatRectToSKRect(dstRect)); 1449 c->clipRect(WebCoreFloatRectToSKRect(dstRect));
1452 c->translate(dstRect.x(), dstRect.y()); 1450 c->translate(dstRect.x(), dstRect.y());
1453 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t()); 1451 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t());
1454 c->translate(-srcRect.x(), -srcRect.y()); 1452 c->translate(-srcRect.x(), -srcRect.y());
1455 video->paintCurrentFrameInContext(gc, IntRect(IntPoint(), IntSize(video->vid eoWidth(), video->videoHeight()))); 1453 video->paintCurrentFrameInContext(gc, IntRect(IntPoint(), IntSize(video->vid eoWidth(), video->videoHeight())));
1456 c->restore(); 1454 c->restore();
1457 } 1455 }
1458 1456
1459 static void drawImageOnContext(SkCanvas* c, GraphicsContext* gc, CanvasImageSour ce* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRec t) 1457 static void drawImageOnContext(SkCanvas* c, GraphicsContext* gc, CanvasImageSour ce* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRec t)
1460 { 1458 {
1461 if (!imageSource->isVideoElement()) { 1459 if (!imageSource->isVideoElement()) {
1462 gc->drawImage(image, dstRect, srcRect, gc->compositeOperation()); 1460 gc->drawImage(image, dstRect, srcRect, gc->compositeOperation());
1463 } else { 1461 } else {
1464 drawVideo(c, gc, static_cast<HTMLVideoElement*>(imageSource), srcRect, d stRect); 1462 drawVideo(c, gc, static_cast<HTMLVideoElement*>(imageSource), srcRect, d stRect);
1465 } 1463 }
1466 } 1464 }
1467 1465
1468 void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource, 1466 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
1469 float sx, float sy, float sw, float sh, 1467 float sx, float sy, float sw, float sh,
1470 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1468 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1471 { 1469 {
1472 RefPtr<Image> image; 1470 RefPtr<Image> image;
1473 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; 1471 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
1474 if (!imageSource->isVideoElement()) { 1472 if (!imageSource->isVideoElement()) {
1475 SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolati le : DontCopySourceImage; // Thunking for == 1473 SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolati le : DontCopySourceImage; // Thunking for ==
1476 image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus); 1474 image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus);
1477 if (sourceImageStatus == UndecodableSourceImageStatus) 1475 if (sourceImageStatus == UndecodableSourceImageStatus)
1478 exceptionState.throwDOMException(InvalidStateError, "The HTMLImageEl ement provided is in the 'broken' state."); 1476 exceptionState.throwDOMException(InvalidStateError, "The HTMLImageEl ement provided is in the 'broken' state.");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 1509
1512 // FIXME: crbug.com/447218 1510 // FIXME: crbug.com/447218
1513 // We make the destination canvas fall out of display list mode by calling 1511 // We make the destination canvas fall out of display list mode by calling
1514 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface 1512 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface
1515 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the 1513 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the
1516 // presentation frame rate of the destination canvas. 1514 // presentation frame rate of the destination canvas.
1517 if (imageSource->isCanvasElement()) 1515 if (imageSource->isCanvasElement())
1518 canvas()->buffer()->willAccessPixels(); 1516 canvas()->buffer()->willAccessPixels();
1519 1517
1520 if (rectContainsTransformedRect(dstRect, clipBounds)) { 1518 if (rectContainsTransformedRect(dstRect, clipBounds)) {
1519 checkOverdraw(dstRect, &c->fillPaint(), imageSource->isOpaque() ? Opaque Image : NonOpaqueImage, ClipFill);
1521 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); 1520 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect);
1522 didDraw(clipBounds); 1521 didDraw(clipBounds);
1523 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { 1522 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
1524 fullCanvasCompositedDraw(bind(&drawImageOnContext, drawingCanvas(), c, i mageSource, image.get(), srcRect, dstRect)); 1523 fullCanvasCompositedDraw(bind(&drawImageOnContext, drawingCanvas(), c, i mageSource, image.get(), srcRect, dstRect));
1525 didDraw(clipBounds); 1524 didDraw(clipBounds);
1526 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { 1525 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) {
1527 clearCanvas(); 1526 clearCanvas(); // takes care of signaling an overdraw
1528 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); 1527 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect);
1529 didDraw(clipBounds); 1528 didDraw(clipBounds);
1530 } else { 1529 } else {
1531 FloatRect dirtyRect; 1530 FloatRect dirtyRect;
1532 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) { 1531 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) {
1533 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), src Rect, dstRect); 1532 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), src Rect, dstRect);
1534 didDraw(dirtyRect); 1533 didDraw(dirtyRect);
1535 } 1534 }
1536 } 1535 }
1537 1536
1538 validateStateStack(); 1537 validateStateStack();
1539 1538
1540 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer()) 1539 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer())
1541 canvas()->buffer()->flush(); 1540 canvas()->buffer()->flush();
1542 1541
1543 if (canvas()->originClean() && wouldTaintOrigin(imageSource)) 1542 if (canvas()->originClean() && wouldTaintOrigin(imageSource))
1544 canvas()->setOriginTainted(); 1543 canvas()->setOriginTainted();
1545 } 1544 }
1546 1545
1547 void CanvasRenderingContext2D::clearCanvas() 1546 void CanvasRenderingContext2D::clearCanvas()
1548 { 1547 {
1549 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); 1548 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
1550 SkCanvas* c = drawingCanvas(); 1549 SkCanvas* c = drawingCanvas();
1551 if (!c) 1550 if (!c)
1552 return; 1551 return;
1553 1552
1553 checkOverdraw(canvasRect, 0, NoImage, ClipFill);
1554 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK); 1554 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
1555 } 1555 }
1556 1556
1557 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const 1557 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const
1558 { 1558 {
1559 FloatQuad quad(rect); 1559 FloatQuad quad(rect);
1560 FloatQuad transformedQuad(transformedRect); 1560 FloatQuad transformedQuad(transformedRect);
1561 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); 1561 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad);
1562 } 1562 }
1563 1563
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 clipRect.intersect(IntRect(0, 0, data->width(), data->height())); 1784 clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
1785 IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy)); 1785 IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
1786 IntRect destRect = enclosingIntRect(clipRect); 1786 IntRect destRect = enclosingIntRect(clipRect);
1787 destRect.move(destOffset); 1787 destRect.move(destOffset);
1788 destRect.intersect(IntRect(IntPoint(), buffer->size())); 1788 destRect.intersect(IntRect(IntPoint(), buffer->size()));
1789 if (destRect.isEmpty()) 1789 if (destRect.isEmpty())
1790 return; 1790 return;
1791 IntRect sourceRect(destRect); 1791 IntRect sourceRect(destRect);
1792 sourceRect.move(-destOffset); 1792 sourceRect.move(-destOffset);
1793 1793
1794 checkOverdraw(destRect, 0, NoImage, UntransformedUnclippedFill);
1795
1794 buffer->putByteArray(Unmultiplied, data->data()->data(), IntSize(data->width (), data->height()), sourceRect, IntPoint(destOffset)); 1796 buffer->putByteArray(Unmultiplied, data->data()->data(), IntSize(data->width (), data->height()), sourceRect, IntPoint(destOffset));
1795 1797
1796 didDraw(destRect); 1798 didDraw(destRect);
1797 } 1799 }
1798 1800
1799 String CanvasRenderingContext2D::font() const 1801 String CanvasRenderingContext2D::font() const
1800 { 1802 {
1801 if (!state().m_realizedFont) 1803 if (!state().m_realizedFont)
1802 return defaultFont; 1804 return defaultFont;
1803 1805
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 } 2377 }
2376 2378
2377 unsigned CanvasRenderingContext2D::hitRegionsCount() const 2379 unsigned CanvasRenderingContext2D::hitRegionsCount() const
2378 { 2380 {
2379 if (m_hitRegionManager) 2381 if (m_hitRegionManager)
2380 return m_hitRegionManager->getHitRegionsCount(); 2382 return m_hitRegionManager->getHitRegionsCount();
2381 2383
2382 return 0; 2384 return 0;
2383 } 2385 }
2384 2386
2387 void CanvasRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint* paint, ImageType imageType, DrawType drawType)
2388 {
2389 SkCanvas* c = drawingCanvas();
2390 if (!c || !canvas()->buffer()->isRecording())
Stephen Chennney 2015/02/11 14:33:20 There's a lot of implicit non-null here. As writte
Justin Novosad 2015/02/11 18:59:54 Those checks are taken care of in drawingCanvas().
Stephen Chennney 2015/02/11 19:29:47 OK.
2391 return;
2392
2393 SkRect deviceRect;
2394 if (drawType == UntransformedUnclippedFill) {
2395 deviceRect = rect;
2396 } else {
2397 ASSERT(drawType == ClipFill);
2398 if (state().m_hasComplexClip)
2399 return;
2400
2401 SkIRect skIBounds;
2402 if (!c->getClipDeviceBounds(&skIBounds))
2403 return;
2404 deviceRect = SkRect::Make(skIBounds);
2405 }
2406
2407 const SkImageInfo& imageInfo = c->imageInfo();
2408 if (!deviceRect.contains(SkRect::MakeWH(imageInfo.width(), imageInfo.height( ))))
2409 return;
2410
2411 bool isSourceOver = true;
2412 unsigned alpha = 0xFF;
2413 if (paint) {
2414 if (paint->getLooper() || paint->getImageFilter() || paint->getMaskFilte r())
2415 return;
2416
2417 SkXfermode* xfermode = paint->getXfermode();
2418 if (xfermode) {
2419 SkXfermode::Mode mode;
2420 if (xfermode->asMode(&mode)) {
2421 isSourceOver = mode == SkXfermode::kSrcOver_Mode;
2422 if (!isSourceOver && mode != SkXfermode::kSrc_Mode && mode != Sk Xfermode::kClear_Mode)
2423 return; // The code below only knows how to handle Src, SrcO ver, and Clear
2424 } else {
2425 // unknown xfermode
2426 ASSERT_NOT_REACHED();
2427 return;
2428 }
2429 }
2430
2431 alpha = paint->getAlpha();
2432
2433 if (isSourceOver && imageType == NoImage) {
2434 SkShader* shader = paint->getShader();
2435 if (shader) {
2436 if (shader->isOpaque() && alpha == 0xFF)
2437 canvas()->buffer()->willOverwriteCanvas();
2438 return;
2439 }
2440 }
2441 }
2442
2443 if (isSourceOver) {
2444 // With source over, we need to certify that alpha == 0xFF for all pixel s
2445 if (imageType == NonOpaqueImage)
2446 return;
2447 if (alpha < 0xFF)
2448 return;
2449 }
2450
2451 canvas()->buffer()->willOverwriteCanvas();
2452 }
2453
2385 } // namespace blink 2454 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698