Chromium Code Reviews| Index: src/core/SkCanvas.cpp |
| diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
| index 34d6aaa0ab4ddbb9ae5f158a846d77636c326642..874a4ee259d782a00f96edaaf05e9badb79d0801 100644 |
| --- a/src/core/SkCanvas.cpp |
| +++ b/src/core/SkCanvas.cpp |
| @@ -115,12 +115,14 @@ struct DeviceCM { |
| SkPaint* fPaint; // may be null (in the future) |
| const SkMatrix* fMatrix; |
| SkMatrix fMatrixStorage; |
| + SkMatrix fStashedMatrix; // Original CTM; used by imageFilter at saveLayer time |
| const bool fDeviceIsBitmapDevice; |
| DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, |
| - bool conservativeRasterClip, bool deviceIsBitmapDevice) |
| + bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMatrix& stashed) |
| : fNext(NULL) |
| , fClip(conservativeRasterClip) |
| + , fStashedMatrix(stashed) |
| , fDeviceIsBitmapDevice(deviceIsBitmapDevice) |
| { |
| if (NULL != device) { |
| @@ -528,7 +530,8 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); |
| fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; |
| - new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, false); |
| + new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, false, |
| + fMCRec->fMatrix); |
| fMCRec->fTopLayer = fMCRec->fLayer; |
| @@ -991,6 +994,22 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav |
| #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
| flags |= kClipToLayer_SaveFlag; |
| #endif |
| + SkLazyPaint lazyP; |
| + SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; |
| + SkMatrix stashedMatrix = fMCRec->fMatrix; |
| + SkMatrix remainder; |
| + SkSize scale; |
| + if (imageFilter && |
| + !stashedMatrix.isScaleTranslate() && stashedMatrix.decomposeScale(&scale, &remainder)) { |
| + // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix |
| + this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); |
| + SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilter( |
| + remainder, SkFilterQuality::kLow_SkFilterQuality, imageFilter)); |
| + imageFilter = matrixFilter.get(); |
| + SkPaint* p = lazyP.set(*paint); |
| + p->setImageFilter(imageFilter); |
| + paint = p; |
| + } |
| // do this before we create the layer. We don't call the public save() since |
| // that would invoke a possibly overridden virtual |
| @@ -999,7 +1018,7 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav |
| fDeviceCMDirty = true; |
| SkIRect ir; |
| - if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { |
| + if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) { |
| return; |
| } |
| @@ -1047,7 +1066,7 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav |
| device->setOrigin(ir.fLeft, ir.fTop); |
| DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRasterClip, |
| - forceSpriteOnRestore)); |
| + forceSpriteOnRestore, stashedMatrix)); |
| device->unref(); |
| layer->fNext = fMCRec->fTopLayer; |
| @@ -1097,6 +1116,8 @@ void SkCanvas::internalRestore() { |
| const SkIPoint& origin = layer->fDevice->getOrigin(); |
| this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
| layer->fPaint, layer->fDeviceIsBitmapDevice); |
| + // restore what we smashed in internalSaveLayer |
| + fMCRec->fMatrix = layer->fStashedMatrix; |
|
Stephen White
2015/05/13 22:18:44
I don't know if it's still relevant, but in my ori
reed2
2015/05/14 10:53:25
Not needed, as we only restore the matrix when we'
|
| // reset this, since internalDrawDevice will have set it to true |
| fDeviceCMDirty = true; |
| SkDELETE(layer); |
| @@ -1104,6 +1125,7 @@ void SkCanvas::internalRestore() { |
| // we're at the root |
| SkASSERT(layer == (void*)fDeviceCMStorage); |
| layer->~DeviceCM(); |
| + // no need to update fMCRec, 'cause we're killing the canvas |
| } |
| } |
| } |
| @@ -1332,11 +1354,15 @@ void SkCanvas::concat(const SkMatrix& matrix) { |
| this->didConcat(matrix); |
| } |
| -void SkCanvas::setMatrix(const SkMatrix& matrix) { |
| - this->checkForDeferredSave(); |
| +void SkCanvas::internalSetMatrix(const SkMatrix& matrix) { |
| fDeviceCMDirty = true; |
| fCachedLocalClipBoundsDirty = true; |
| fMCRec->fMatrix = matrix; |
| +} |
| + |
| +void SkCanvas::setMatrix(const SkMatrix& matrix) { |
| + this->checkForDeferredSave(); |
| + this->internalSetMatrix(matrix); |
| this->didSetMatrix(matrix); |
| } |