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

Side by Side Diff: Source/platform/graphics/GraphicsContext.cpp

Issue 1093673002: Removing the dependency on GraphicsContext for drawing images in 2D canvas (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 8 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) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 24 matching lines...) Expand all
35 #include "platform/graphics/ImageBuffer.h" 35 #include "platform/graphics/ImageBuffer.h"
36 #include "platform/weborigin/KURL.h" 36 #include "platform/weborigin/KURL.h"
37 #include "third_party/skia/include/core/SkAnnotation.h" 37 #include "third_party/skia/include/core/SkAnnotation.h"
38 #include "third_party/skia/include/core/SkColorFilter.h" 38 #include "third_party/skia/include/core/SkColorFilter.h"
39 #include "third_party/skia/include/core/SkData.h" 39 #include "third_party/skia/include/core/SkData.h"
40 #include "third_party/skia/include/core/SkPicture.h" 40 #include "third_party/skia/include/core/SkPicture.h"
41 #include "third_party/skia/include/core/SkPictureRecorder.h" 41 #include "third_party/skia/include/core/SkPictureRecorder.h"
42 #include "third_party/skia/include/core/SkRRect.h" 42 #include "third_party/skia/include/core/SkRRect.h"
43 #include "third_party/skia/include/core/SkRefCnt.h" 43 #include "third_party/skia/include/core/SkRefCnt.h"
44 #include "third_party/skia/include/effects/SkCornerPathEffect.h" 44 #include "third_party/skia/include/effects/SkCornerPathEffect.h"
45 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
46 #include "third_party/skia/include/effects/SkLumaColorFilter.h" 45 #include "third_party/skia/include/effects/SkLumaColorFilter.h"
47 #include "third_party/skia/include/effects/SkPictureImageFilter.h" 46 #include "third_party/skia/include/effects/SkPictureImageFilter.h"
48 #include "third_party/skia/include/utils/SkNullCanvas.h" 47 #include "third_party/skia/include/utils/SkNullCanvas.h"
49 #include "wtf/Assertions.h" 48 #include "wtf/Assertions.h"
50 #include "wtf/MathExtras.h" 49 #include "wtf/MathExtras.h"
51 50
52 namespace blink { 51 namespace blink {
53 52
54 class GraphicsContext::RecordingState { 53 class GraphicsContext::RecordingState {
55 WTF_MAKE_FAST_ALLOCATED(GraphicsContext::RecordingState); 54 WTF_MAKE_FAST_ALLOCATED(GraphicsContext::RecordingState);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 if (contextDisabled()) 301 if (contextDisabled())
303 return; 302 return;
304 303
305 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create(); 304 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
306 if (!color.alpha()) { 305 if (!color.alpha()) {
307 if (shadowMode == DrawShadowOnly) { 306 if (shadowMode == DrawShadowOnly) {
308 // shadow only, but there is no shadow: use an empty draw looper to disable rendering of the source primitive 307 // shadow only, but there is no shadow: use an empty draw looper to disable rendering of the source primitive
309 setDrawLooper(drawLooperBuilder.release()); 308 setDrawLooper(drawLooperBuilder.release());
310 return; 309 return;
311 } 310 }
312 clearShadow(); 311 clearDrawLooper();
313 return; 312 return;
314 } 313 }
315 314
316 drawLooperBuilder->addShadow(offset, blur, color, shadowTransformMode, shado wAlphaMode); 315 drawLooperBuilder->addShadow(offset, blur, color, shadowTransformMode, shado wAlphaMode);
317 if (shadowMode == DrawShadowAndForeground) { 316 if (shadowMode == DrawShadowAndForeground) {
318 drawLooperBuilder->addUnmodifiedContent(); 317 drawLooperBuilder->addUnmodifiedContent();
319 } 318 }
320 setDrawLooper(drawLooperBuilder.release()); 319 setDrawLooper(drawLooperBuilder.release());
321
322 if (shadowTransformMode == DrawLooperBuilder::ShadowIgnoresTransforms
323 && shadowAlphaMode == DrawLooperBuilder::ShadowRespectsAlpha) {
324 // This image filter will be used in place of the drawLooper created abo ve but only for drawing non-opaque bitmaps;
325 // see preparePaintForDrawRectToRect().
326 SkColor skColor = color.rgb();
327 // These constants are from RadiusToSigma() from DrawLooperBuilder.cpp.
328 const SkScalar sigma = 0.288675f * blur + 0.5f;
329 SkDropShadowImageFilter::ShadowMode dropShadowMode = shadowMode == DrawS hadowAndForeground ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMod e : SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
330 RefPtr<SkImageFilter> filter = adoptRef(SkDropShadowImageFilter::Create( offset.width(), offset.height(), sigma, sigma, skColor, dropShadowMode));
331 setDropShadowImageFilter(filter);
332 }
333 } 320 }
334 321
335 void GraphicsContext::setDrawLooper(PassOwnPtr<DrawLooperBuilder> drawLooperBuil der) 322 void GraphicsContext::setDrawLooper(PassOwnPtr<DrawLooperBuilder> drawLooperBuil der)
336 { 323 {
337 if (contextDisabled()) 324 if (contextDisabled())
338 return; 325 return;
339 326
340 mutableState()->setDrawLooper(drawLooperBuilder->detachDrawLooper()); 327 mutableState()->setDrawLooper(drawLooperBuilder->detachDrawLooper());
341 } 328 }
342 329
343 void GraphicsContext::clearDrawLooper() 330 void GraphicsContext::clearDrawLooper()
344 { 331 {
345 if (contextDisabled()) 332 if (contextDisabled())
346 return; 333 return;
347 334
348 mutableState()->clearDrawLooper(); 335 mutableState()->clearDrawLooper();
349 } 336 }
350 337
351 void GraphicsContext::setDropShadowImageFilter(PassRefPtr<SkImageFilter> imageFi lter)
352 {
353 if (contextDisabled())
354 return;
355
356 mutableState()->setDropShadowImageFilter(imageFilter);
357 }
358
359 void GraphicsContext::clearDropShadowImageFilter()
360 {
361 if (contextDisabled())
362 return;
363
364 mutableState()->clearDropShadowImageFilter();
365 }
366
367 SkMatrix GraphicsContext::getTotalMatrix() const 338 SkMatrix GraphicsContext::getTotalMatrix() const
368 { 339 {
369 // FIXME: this is a hack to avoid changing all call sites of getTotalMatrix( ) to not use this method. 340 // FIXME: this is a hack to avoid changing all call sites of getTotalMatrix( ) to not use this method.
370 // The code needs to be cleand up after Slimming Paint is launched. 341 // The code needs to be cleand up after Slimming Paint is launched.
371 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) 342 if (RuntimeEnabledFeatures::slimmingPaintEnabled())
372 return SkMatrix::I(); 343 return SkMatrix::I();
373 344
374 if (contextDisabled() || !m_canvas) 345 if (contextDisabled() || !m_canvas)
375 return SkMatrix::I(); 346 return SkMatrix::I();
376 347
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 SkPaint layerPaint; 414 SkPaint layerPaint;
444 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255)); 415 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255));
445 layerPaint.setXfermodeMode(xfermode); 416 layerPaint.setXfermodeMode(xfermode);
446 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g et()); 417 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g et());
447 layerPaint.setImageFilter(imageFilter); 418 layerPaint.setImageFilter(imageFilter);
448 419
449 if (bounds) { 420 if (bounds) {
450 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds); 421 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds);
451 saveLayer(&skBounds, &layerPaint); 422 saveLayer(&skBounds, &layerPaint);
452 } else { 423 } else {
453 saveLayer(0, &layerPaint); 424 saveLayer(nullptr, &layerPaint);
454 } 425 }
455 426
456 #if ENABLE(ASSERT) 427 #if ENABLE(ASSERT)
457 ++m_layerCount; 428 ++m_layerCount;
458 #endif 429 #endif
459 } 430 }
460 431
461 void GraphicsContext::endLayer() 432 void GraphicsContext::endLayer()
462 { 433 {
463 if (contextDisabled()) 434 if (contextDisabled())
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 { 996 {
1026 if (!image) 997 if (!image)
1027 return; 998 return;
1028 drawImage(image, FloatRect(r), FloatRect(FloatPoint(), FloatSize(image->size ())), op, shouldRespectImageOrientation); 999 drawImage(image, FloatRect(r), FloatRect(FloatPoint(), FloatSize(image->size ())), op, shouldRespectImageOrientation);
1029 } 1000 }
1030 1001
1031 void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float Rect& src, SkXfermode::Mode op, RespectImageOrientationEnum shouldRespectImageOr ientation) 1002 void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float Rect& src, SkXfermode::Mode op, RespectImageOrientationEnum shouldRespectImageOr ientation)
1032 { 1003 {
1033 if (contextDisabled() || !image) 1004 if (contextDisabled() || !image)
1034 return; 1005 return;
1035 image->draw(this, dest, src, op, shouldRespectImageOrientation); 1006
1007 SkPaint imagePaint = immutableState()->fillPaint();
1008 imagePaint.setXfermodeMode(op);
1009 imagePaint.setFilterQuality(getFilterQuality(image, dest, src));
1010
1011 image->draw(m_canvas, imagePaint, dest, src, shouldRespectImageOrientation);
1012 }
1013
1014 SkFilterQuality GraphicsContext::getFilterQuality(Image* image, const FloatRect& dest, const FloatRect& src) const
1015 {
1016 InterpolationQuality resampling;
1017 if (printing()) {
1018 resampling = InterpolationNone;
1019 } else if (image->isLazyDecodedBitmap()) {
1020 resampling = InterpolationHigh;
1021 } else {
1022 // Take into account scale applied to the canvas when computing sampling mode (e.g. CSS scale or page scale).
1023 SkRect destRectTarget = dest;
1024 SkMatrix totalMatrix = getTotalMatrix();
1025 if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPersp ective_Mask)))
1026 totalMatrix.mapRect(&destRectTarget, dest);
1027
1028 resampling = computeInterpolationQuality(totalMatrix,
1029 SkScalarToFloat(src.width()), SkScalarToFloat(src.height()),
1030 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar get.height()),
1031 image->isImmutableBitmap());
1032 }
1033
1034 if (resampling == InterpolationNone) {
1035 // FIXME: This is to not break tests (it results in the filter bitmap fl ag
1036 // being set to true). We need to decide if we respect InterpolationNone
1037 // being returned from computeInterpolationQuality.
1038 resampling = InterpolationLow;
1039 }
1040 return static_cast<SkFilterQuality>(limitInterpolationQuality(this, resampli ng));
1036 } 1041 }
1037 1042
1038 void GraphicsContext::drawTiledImage(Image* image, const IntRect& destRect, cons t IntPoint& srcPoint, const IntSize& tileSize, SkXfermode::Mode op, const IntSiz e& repeatSpacing) 1043 void GraphicsContext::drawTiledImage(Image* image, const IntRect& destRect, cons t IntPoint& srcPoint, const IntSize& tileSize, SkXfermode::Mode op, const IntSiz e& repeatSpacing)
1039 { 1044 {
1040 if (contextDisabled() || !image) 1045 if (contextDisabled() || !image)
1041 return; 1046 return;
1042 image->drawTiled(this, destRect, srcPoint, tileSize, op, repeatSpacing); 1047 image->drawTiled(this, destRect, srcPoint, tileSize, op, repeatSpacing);
1043 } 1048 }
1044 1049
1045 void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const In tRect& srcRect, 1050 void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const In tRect& srcRect,
(...skipping 22 matching lines...) Expand all
1068 1073
1069 void GraphicsContext::writePixels(const SkImageInfo& info, const void* pixels, s ize_t rowBytes, int x, int y) 1074 void GraphicsContext::writePixels(const SkImageInfo& info, const void* pixels, s ize_t rowBytes, int x, int y)
1070 { 1075 {
1071 if (contextDisabled()) 1076 if (contextDisabled())
1072 return; 1077 return;
1073 ASSERT(m_canvas); 1078 ASSERT(m_canvas);
1074 1079
1075 m_canvas->writePixels(info, pixels, rowBytes, x, y); 1080 m_canvas->writePixels(info, pixels, rowBytes, x, y);
1076 } 1081 }
1077 1082
1078 void GraphicsContext::drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
1079 const SkRect& dst, const SkPaint* paint)
1080 {
1081 // Textures are bound to the blink main-thread GrContext, which can not be
1082 // used on the compositor raster thread.
1083 // FIXME: Mailbox support would make this possible in the GPU-raster case.
1084 ASSERT(!isRecording() || !bitmap.getTexture());
1085 if (contextDisabled())
1086 return;
1087
1088 SkCanvas::DrawBitmapRectFlags flags =
1089 immutableState()->shouldClampToSourceRect() ? SkCanvas::kNone_DrawBitmap RectFlag : SkCanvas::kBleed_DrawBitmapRectFlag;
1090
1091 ASSERT(m_canvas);
1092 m_canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
1093 }
1094
1095 void GraphicsContext::drawOval(const SkRect& oval, const SkPaint& paint) 1083 void GraphicsContext::drawOval(const SkRect& oval, const SkPaint& paint)
1096 { 1084 {
1097 if (contextDisabled()) 1085 if (contextDisabled())
1098 return; 1086 return;
1099 ASSERT(m_canvas); 1087 ASSERT(m_canvas);
1100 1088
1101 m_canvas->drawOval(oval, paint); 1089 m_canvas->drawOval(oval, paint);
1102 } 1090 }
1103 1091
1104 void GraphicsContext::drawPath(const SkPath& path, const SkPaint& paint) 1092 void GraphicsContext::drawPath(const SkPath& path, const SkPaint& paint)
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 { 1611 {
1624 static const SkPMColor colors[] = { 1612 static const SkPMColor colors[] = {
1625 SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red 1613 SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red
1626 SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0) // More transparent gray 1614 SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0) // More transparent gray
1627 }; 1615 };
1628 1616
1629 return colors[index]; 1617 return colors[index];
1630 } 1618 }
1631 #endif 1619 #endif
1632 1620
1633 int GraphicsContext::preparePaintForDrawRectToRect(
1634 SkPaint* paint,
1635 const SkRect& srcRect,
1636 const SkRect& destRect,
1637 SkXfermode::Mode compositeOp,
1638 bool isBitmapWithAlpha,
1639 bool isLazyDecoded,
1640 bool isDataComplete) const
1641 {
1642 int initialSaveCount = m_canvas->getSaveCount();
1643
1644 paint->setColorFilter(this->colorFilter());
1645 paint->setAlpha(this->getNormalizedAlpha());
1646 bool usingImageFilter = false;
1647 if (dropShadowImageFilter() && isBitmapWithAlpha) {
1648 SkMatrix ctm = getTotalMatrix();
1649 SkMatrix invCtm;
1650 if (ctm.invert(&invCtm)) {
1651 usingImageFilter = true;
1652 // The image filter is meant to ignore tranforms with respect to
1653 // the shadow parameters. The matrix tweaks below ensures that the i mage
1654 // filter is applied in post-transform space. We use concat() instea d of
1655 // setMatrix() in case this goes into a recording canvas which may n eed to
1656 // respect a parent transform at playback time.
1657 m_canvas->save();
1658 m_canvas->concat(invCtm);
1659 SkRect bounds = destRect;
1660 ctm.mapRect(&bounds);
1661 SkRect filteredBounds;
1662 dropShadowImageFilter()->computeFastBounds(bounds, &filteredBounds);
1663 SkPaint layerPaint;
1664 layerPaint.setXfermodeMode(compositeOp);
1665 layerPaint.setImageFilter(dropShadowImageFilter());
1666 m_canvas->saveLayer(&filteredBounds, &layerPaint);
1667 m_canvas->concat(ctm);
1668 }
1669 }
1670
1671 if (!usingImageFilter) {
1672 paint->setXfermodeMode(compositeOp);
1673 paint->setLooper(this->drawLooper());
1674 }
1675
1676 paint->setAntiAlias(shouldDrawAntiAliased(this, destRect));
1677
1678 InterpolationQuality resampling;
1679 if (this->isAccelerated()) {
1680 resampling = InterpolationLow;
1681 } else if (this->printing()) {
1682 resampling = InterpolationNone;
1683 } else if (isLazyDecoded) {
1684 resampling = InterpolationHigh;
1685 } else {
1686 // Take into account scale applied to the canvas when computing sampling mode (e.g. CSS scale or page scale).
1687 SkRect destRectTarget = destRect;
1688 SkMatrix totalMatrix = this->getTotalMatrix();
1689 if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPersp ective_Mask)))
1690 totalMatrix.mapRect(&destRectTarget, destRect);
1691
1692 resampling = computeInterpolationQuality(totalMatrix,
1693 SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()),
1694 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar get.height()),
1695 isDataComplete);
1696 }
1697
1698 if (resampling == InterpolationNone) {
1699 // FIXME: This is to not break tests (it results in the filter bitmap fl ag
1700 // being set to true). We need to decide if we respect InterpolationNone
1701 // being returned from computeInterpolationQuality.
1702 resampling = InterpolationLow;
1703 }
1704 resampling = limitInterpolationQuality(this, resampling);
1705 paint->setFilterQuality(static_cast<SkFilterQuality>(resampling));
1706
1707 return initialSaveCount;
1708 }
1709
1710 } // namespace blink 1621 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698