Chromium Code Reviews| Index: src/core/SkCanvas.cpp |
| diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
| index 6beb26e4cad9c42d70b99e44f7d62f867a15e222..b6d3cf99761607cca1da0f78a3a65a910fcf542a 100644 |
| --- a/src/core/SkCanvas.cpp |
| +++ b/src/core/SkCanvas.cpp |
| @@ -67,6 +67,19 @@ void SkCanvas::predrawNotify() { |
| /////////////////////////////////////////////////////////////////////////////// |
| +static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { |
| + const uint32_t propFlags = props.flags(); |
| + if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { |
| + flags &= ~SkPaint::kDither_Flag; |
| + } |
| + if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { |
| + flags &= ~SkPaint::kAntiAlias_Flag; |
| + } |
| + return flags; |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| /* This is the record we keep for each SkBaseDevice that the user installs. |
| The clip/matrix/proc are fields that reflect the top of the save/restore |
| stack. Whenever the canvas changes, it marks a dirty flag, and then before |
| @@ -250,12 +263,12 @@ private: |
| class AutoDrawLooper { |
| public: |
| - AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, |
| + AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, |
| bool skipLayerForImageFilter = false, |
| const SkRect* bounds = NULL) : fOrigPaint(paint) { |
| fCanvas = canvas; |
| fFilter = canvas->getDrawFilter(); |
| - fPaint = NULL; |
| + fPaint = &fOrigPaint; |
| fSaveCount = canvas->getSaveCount(); |
| fDoClearImageFilter = false; |
| fDone = false; |
| @@ -280,6 +293,15 @@ public: |
| // can we be marked as simple? |
| fIsSimple = !fFilter && !fDoClearImageFilter; |
| } |
| + |
| + uint32_t oldFlags = paint.getFlags(); |
| + fNewPaintFlags = filter_paint_flags(props, oldFlags); |
| + if (fIsSimple && (fNewPaintFlags != oldFlags)) { |
| + SkPaint* paint = fLazyPaint.set(fOrigPaint); |
| + paint->setFlags(fNewPaintFlags); |
| + fPaint = paint; |
| + // if we're not simple, doNext() will take care of calling setFlags() |
| + } |
| } |
| ~AutoDrawLooper() { |
| @@ -299,7 +321,6 @@ public: |
| return false; |
| } else if (fIsSimple) { |
| fDone = true; |
| - fPaint = &fOrigPaint; |
| return !fPaint->nothingToDraw(); |
| } else { |
| return this->doNext(drawType); |
| @@ -313,6 +334,7 @@ private: |
| SkDrawFilter* fFilter; |
| const SkPaint* fPaint; |
| int fSaveCount; |
| + uint32_t fNewPaintFlags; |
| bool fDoClearImageFilter; |
| bool fDone; |
| bool fIsSimple; |
| @@ -328,6 +350,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); |
| SkPaint* paint = fLazyPaint.set(fOrigPaint); |
| + paint->setFlags(fNewPaintFlags); |
| if (fDoClearImageFilter) { |
| paint->setImageFilter(NULL); |
| @@ -363,18 +386,19 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| } |
| #include "SkColorPriv.h" |
| +#include "SkDeviceProperties.h" |
|
bungeman-skia
2014/09/18 21:14:10
Is this being used here?
reed1
2014/09/18 21:24:41
Done.
|
| ////////// macros to place around the internal draw calls ////////////////// |
| #define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ |
| this->predrawNotify(); \ |
| - AutoDrawLooper looper(this, paint, true); \ |
| + AutoDrawLooper looper(this, fProps, paint, true); \ |
| while (looper.next(type)) { \ |
| SkDrawIter iter(this); |
| #define LOOPER_BEGIN(paint, type, bounds) \ |
| this->predrawNotify(); \ |
| - AutoDrawLooper looper(this, paint, false, bounds); \ |
| + AutoDrawLooper looper(this, fProps, paint, false, bounds); \ |
| while (looper.next(type)) { \ |
| SkDrawIter iter(this); |
| @@ -382,6 +406,10 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| //////////////////////////////////////////////////////////////////////////// |
| +void SkCanvas::setupDevice(SkBaseDevice* device) { |
| + device->setPixelGeometry(fProps.pixelGeometry()); |
| +} |
| + |
| SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); |
| fCachedLocalClipBounds.setEmpty(); |
| @@ -393,10 +421,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| fCullCount = 0; |
| fMetaData = NULL; |
| - if (device && device->forceConservativeRasterClip()) { |
| - fConservativeRasterClip = true; |
| - } |
| - |
| fMCRec = (MCRec*)fMCStack.push_back(); |
| new (fMCRec) MCRec(fConservativeRasterClip); |
| @@ -406,6 +430,10 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| fSurfaceBase = NULL; |
| if (device) { |
| + this->setupDevice(device); |
| + if (device->forceConservativeRasterClip()) { |
| + fConservativeRasterClip = true; |
| + } |
| device->onAttachToCanvas(this); |
| fMCRec->fLayer->fDevice = SkRef(device); |
| fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height())); |
| @@ -415,6 +443,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| SkCanvas::SkCanvas() |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
| { |
| inc_canvas(); |
| @@ -436,8 +465,17 @@ private: |
| typedef SkBitmapDevice INHERITED; |
| }; |
| +static SkSurfaceProps props_or_default(const SkSurfaceProps* props) { |
| + if (props) { |
| + return *props; |
| + } else { |
| + return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); |
| + } |
| +} |
| + |
| SkCanvas::SkCanvas(int width, int height) |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
| { |
| inc_canvas(); |
| @@ -446,14 +484,16 @@ SkCanvas::SkCanvas(int width, int height) |
| SkCanvas::SkCanvas(int width, int height, InitFlags flags) |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
| { |
| inc_canvas(); |
| this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref(); |
| } |
| -SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) |
| +SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags) |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(props_or_default(props)) |
| { |
| inc_canvas(); |
| @@ -462,18 +502,31 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) |
| SkCanvas::SkCanvas(SkBaseDevice* device) |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
| { |
| inc_canvas(); |
| this->init(device, kDefault_InitFlags); |
| } |
| -SkCanvas::SkCanvas(const SkBitmap& bitmap) |
| +SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) |
| : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(props) |
| { |
| inc_canvas(); |
| + |
| + SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
| + this->init(device, kDefault_InitFlags); |
| +} |
| - this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref(); |
| +SkCanvas::SkCanvas(const SkBitmap& bitmap) |
| + : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| + , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
| +{ |
| + inc_canvas(); |
| + |
| + SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
| + this->init(device, kDefault_InitFlags); |
| } |
| SkCanvas::~SkCanvas() { |
| @@ -564,6 +617,7 @@ SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { |
| SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); |
| rootDevice = device; |
| + this->setupDevice(device); |
| fDeviceCMDirty = true; |
| @@ -899,6 +953,7 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Save |
| SkDebugf("Unable to create device for layer."); |
| return count; |
| } |
| + this->setupDevice(device); |
| device->setOrigin(ir.fLeft, ir.fTop); |
| DeviceCM* layer = SkNEW_ARGS(DeviceCM, |
| @@ -994,13 +1049,16 @@ bool SkCanvas::isDrawingToLayer() const { |
| return fSaveLayerCount > 0; |
| } |
| -SkSurface* SkCanvas::newSurface(const SkImageInfo& info) { |
| - return this->onNewSurface(info); |
| +SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { |
| + if (NULL == props) { |
| + props = &fProps; |
| + } |
| + return this->onNewSurface(info, *props); |
| } |
| -SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { |
| +SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { |
| SkBaseDevice* dev = this->getDevice(); |
| - return dev ? dev->newSurface(info) : NULL; |
| + return dev ? dev->newSurface(info, props) : NULL; |
| } |
| SkImageInfo SkCanvas::imageInfo() const { |