OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkCanvasPriv.h" | 9 #include "SkCanvasPriv.h" |
10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 #define inc_layer() | 73 #define inc_layer() |
74 #define dec_layer() | 74 #define dec_layer() |
75 #define inc_rec() | 75 #define inc_rec() |
76 #define dec_rec() | 76 #define dec_rec() |
77 #define inc_canvas() | 77 #define inc_canvas() |
78 #define dec_canvas() | 78 #define dec_canvas() |
79 #endif | 79 #endif |
80 | 80 |
81 typedef SkTLazy<SkPaint> SkLazyPaint; | 81 typedef SkTLazy<SkPaint> SkLazyPaint; |
82 | 82 |
83 void SkCanvas::predrawNotify() { | |
84 if (fSurfaceBase) { | |
85 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); | |
86 } | |
87 } | |
88 | |
89 /////////////////////////////////////////////////////////////////////////////// | 83 /////////////////////////////////////////////////////////////////////////////// |
90 | 84 |
91 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags)
{ | 85 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags)
{ |
92 const uint32_t propFlags = props.flags(); | 86 const uint32_t propFlags = props.flags(); |
93 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { | 87 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { |
94 flags &= ~SkPaint::kDither_Flag; | 88 flags &= ~SkPaint::kDither_Flag; |
95 } | 89 } |
96 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { | 90 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { |
97 flags &= ~SkPaint::kAntiAlias_Flag; | 91 flags &= ~SkPaint::kAntiAlias_Flag; |
98 } | 92 } |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 if (fPaint->nothingToDraw()) { | 397 if (fPaint->nothingToDraw()) { |
404 fPaint = NULL; | 398 fPaint = NULL; |
405 return false; | 399 return false; |
406 } | 400 } |
407 return true; | 401 return true; |
408 } | 402 } |
409 | 403 |
410 ////////// macros to place around the internal draw calls ////////////////// | 404 ////////// macros to place around the internal draw calls ////////////////// |
411 | 405 |
412 #define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ | 406 #define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ |
413 this->predrawNotify(); \ | |
414 AutoDrawLooper looper(this, fProps, paint, true); \ | 407 AutoDrawLooper looper(this, fProps, paint, true); \ |
415 while (looper.next(type)) { \ | 408 while (looper.next(type)) { \ |
416 SkDrawIter iter(this); | 409 SkDrawIter iter(this); |
417 | 410 |
418 #define LOOPER_BEGIN(paint, type, bounds) \ | 411 #define LOOPER_BEGIN(paint, type, bounds) \ |
419 this->predrawNotify(); \ | |
420 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ | 412 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ |
421 while (looper.next(type)) { \ | 413 while (looper.next(type)) { \ |
422 SkDrawIter iter(this); | 414 SkDrawIter iter(this); |
423 | 415 |
424 #define LOOPER_END } | 416 #define LOOPER_END } |
425 | 417 |
426 //////////////////////////////////////////////////////////////////////////// | 418 //////////////////////////////////////////////////////////////////////////// |
427 | 419 |
428 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { | 420 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
429 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; | 421 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; |
430 fCachedLocalClipBounds.setEmpty(); | 422 fCachedLocalClipBounds.setEmpty(); |
431 fCachedLocalClipBoundsDirty = true; | 423 fCachedLocalClipBoundsDirty = true; |
432 fAllowSoftClip = true; | 424 fAllowSoftClip = true; |
433 fAllowSimplifyClip = false; | 425 fAllowSimplifyClip = false; |
434 fDeviceCMDirty = true; | 426 fDeviceCMDirty = true; |
435 fSaveCount = 1; | 427 fSaveCount = 1; |
436 fMetaData = NULL; | 428 fMetaData = NULL; |
437 | 429 |
438 fMCRec = (MCRec*)fMCStack.push_back(); | 430 fMCRec = (MCRec*)fMCStack.push_back(); |
439 new (fMCRec) MCRec(fConservativeRasterClip); | 431 new (fMCRec) MCRec(fConservativeRasterClip); |
440 | 432 |
441 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster
Clip)); | 433 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster
Clip)); |
442 fMCRec->fTopLayer = fMCRec->fLayer; | 434 fMCRec->fTopLayer = fMCRec->fLayer; |
443 | 435 |
444 fSurfaceBase = NULL; | |
445 | |
446 fClipStack.reset(SkNEW(SkClipStack)); | 436 fClipStack.reset(SkNEW(SkClipStack)); |
447 | 437 |
448 if (device) { | 438 if (device) { |
449 device->initForRootLayer(fProps.pixelGeometry()); | 439 device->initForRootLayer(fProps.pixelGeometry()); |
450 if (device->forceConservativeRasterClip()) { | 440 if (device->forceConservativeRasterClip()) { |
451 fConservativeRasterClip = true; | 441 fConservativeRasterClip = true; |
452 } | 442 } |
453 device->onAttachToCanvas(this); | 443 device->onAttachToCanvas(this); |
454 fMCRec->fLayer->fDevice = SkRef(device); | 444 fMCRec->fLayer->fDevice = SkRef(device); |
455 fMCRec->fRasterClip.setRect(device->getGlobalBounds()); | 445 fMCRec->fRasterClip.setRect(device->getGlobalBounds()); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 // if x or y are negative, then we have to adjust pixels | 701 // if x or y are negative, then we have to adjust pixels |
712 if (x > 0) { | 702 if (x > 0) { |
713 x = 0; | 703 x = 0; |
714 } | 704 } |
715 if (y > 0) { | 705 if (y > 0) { |
716 y = 0; | 706 y = 0; |
717 } | 707 } |
718 // here x,y are either 0 or negative | 708 // here x,y are either 0 or negative |
719 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); | 709 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); |
720 | 710 |
721 // Tell our owning surface to bump its generation ID | |
722 this->predrawNotify(); | |
723 | |
724 // The device can assert that the requested area is always contained in its
bounds | 711 // The device can assert that the requested area is always contained in its
bounds |
725 return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); | 712 return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); |
726 } | 713 } |
727 | 714 |
728 SkCanvas* SkCanvas::canvasForDrawIter() { | 715 SkCanvas* SkCanvas::canvasForDrawIter() { |
729 return this; | 716 return this; |
730 } | 717 } |
731 | 718 |
732 ////////////////////////////////////////////////////////////////////////////// | 719 ////////////////////////////////////////////////////////////////////////////// |
733 | 720 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 LOOPER_END | 1096 LOOPER_END |
1110 } | 1097 } |
1111 | 1098 |
1112 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, | 1099 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, |
1113 const SkPaint* paint) { | 1100 const SkPaint* paint) { |
1114 SkPaint tmp; | 1101 SkPaint tmp; |
1115 if (NULL == paint) { | 1102 if (NULL == paint) { |
1116 paint = &tmp; | 1103 paint = &tmp; |
1117 } | 1104 } |
1118 | 1105 |
| 1106 SkAutoTUnref<SkImage> srcImage; |
| 1107 |
1119 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) | 1108 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) |
1120 while (iter.next()) { | 1109 while (iter.next()) { |
1121 SkBaseDevice* dstDev = iter.fDevice; | 1110 SkBaseDevice* dstDev = iter.fDevice; |
1122 paint = &looper.paint(); | 1111 paint = &looper.paint(); |
1123 SkImageFilter* filter = paint->getImageFilter(); | 1112 SkImageFilter* filter = paint->getImageFilter(); |
1124 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; | 1113 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; |
1125 if (filter && !dstDev->canHandleImageFilter(filter)) { | 1114 if (filter && !dstDev->canHandleImageFilter(filter)) { |
1126 SkDeviceImageFilterProxy proxy(dstDev, fProps); | 1115 SkDeviceImageFilterProxy proxy(dstDev, fProps); |
1127 SkBitmap dst; | 1116 SkBitmap dst; |
1128 SkIPoint offset = SkIPoint::Make(0, 0); | 1117 SkIPoint offset = SkIPoint::Make(0, 0); |
1129 const SkBitmap& src = srcDev->accessBitmap(false); | 1118 if (NULL == srcImage) { |
| 1119 srcImage.reset(srcDev->newImageSnapshot()); |
| 1120 if (NULL == srcImage) { |
| 1121 return; |
| 1122 } |
| 1123 } |
1130 SkMatrix matrix = *iter.fMatrix; | 1124 SkMatrix matrix = *iter.fMatrix; |
1131 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()
)); | 1125 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()
)); |
1132 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height
()); | 1126 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height
()); |
1133 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache
()); | 1127 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache
()); |
1134 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); | 1128 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); |
1135 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { | 1129 SkBitmap srcBitmap; // TODO: remove once filters accept SkImage |
1136 SkPaint tmpUnfiltered(*paint); | 1130 #if SK_SUPPORT_GPU |
1137 tmpUnfiltered.setImageFilter(NULL); | 1131 // TODO: Gpu devices need bitmap that came from gpu, not through |
1138 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of
fset.y(), | 1132 // getROPixels. Remove once filters accept SkImage. |
1139 tmpUnfiltered); | 1133 if (NULL != srcImage->getTexture()) { |
| 1134 SkImageFilter::WrapTexture(srcImage->getTexture(), srcImage->wid
th(), |
| 1135 srcImage->height(), &srcBitmap); |
| 1136 } else |
| 1137 #endif |
| 1138 { |
| 1139 as_IB(srcImage)->getROPixels(&srcBitmap); |
| 1140 } |
| 1141 if (!srcBitmap.empty()) { |
| 1142 if (filter->filterImage(&proxy, srcBitmap, ctx, &dst, &offset))
{ |
| 1143 SkPaint tmpUnfiltered(*paint); |
| 1144 tmpUnfiltered.setImageFilter(NULL); |
| 1145 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y()
+ offset.y(), |
| 1146 tmpUnfiltered); |
| 1147 } |
1140 } | 1148 } |
1141 } else { | 1149 } else { |
1142 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); | 1150 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); |
1143 } | 1151 } |
1144 } | 1152 } |
1145 LOOPER_END | 1153 LOOPER_END |
1146 } | 1154 } |
1147 | 1155 |
1148 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint*
paint) { | 1156 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint*
paint) { |
1149 if (gTreatSpriteAsBitmap) { | 1157 if (gTreatSpriteAsBitmap) { |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 } | 1719 } |
1712 void SkCanvas::drawImageAsSprite(const SkImage& image, int left, int top, const
SkPaint* paint) { | 1720 void SkCanvas::drawImageAsSprite(const SkImage& image, int left, int top, const
SkPaint* paint) { |
1713 this->onDrawImageAsSprite(image, left, top, paint); | 1721 this->onDrawImageAsSprite(image, left, top, paint); |
1714 } | 1722 } |
1715 | 1723 |
1716 ////////////////////////////////////////////////////////////////////////////// | 1724 ////////////////////////////////////////////////////////////////////////////// |
1717 // These are the virtual drawing methods | 1725 // These are the virtual drawing methods |
1718 ////////////////////////////////////////////////////////////////////////////// | 1726 ////////////////////////////////////////////////////////////////////////////// |
1719 | 1727 |
1720 void SkCanvas::onDiscard() { | 1728 void SkCanvas::onDiscard() { |
1721 if (fSurfaceBase) { | 1729 if (NULL != this->getDevice()) { |
1722 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); | 1730 this->getDevice()->discard(); |
1723 } | 1731 } |
1724 } | 1732 } |
1725 | 1733 |
1726 void SkCanvas::onDrawPaint(const SkPaint& paint) { | 1734 void SkCanvas::onDrawPaint(const SkPaint& paint) { |
1727 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); | 1735 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); |
1728 this->internalDrawPaint(paint); | 1736 this->internalDrawPaint(paint); |
1729 } | 1737 } |
1730 | 1738 |
1731 void SkCanvas::internalDrawPaint(const SkPaint& paint) { | 1739 void SkCanvas::internalDrawPaint(const SkPaint& paint) { |
1732 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) | 1740 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 } | 2631 } |
2624 | 2632 |
2625 if (matrix) { | 2633 if (matrix) { |
2626 canvas->concat(*matrix); | 2634 canvas->concat(*matrix); |
2627 } | 2635 } |
2628 } | 2636 } |
2629 | 2637 |
2630 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2638 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2631 fCanvas->restoreToCount(fSaveCount); | 2639 fCanvas->restoreToCount(fSaveCount); |
2632 } | 2640 } |
OLD | NEW |