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

Side by Side Diff: src/core/SkCanvas.cpp

Issue 1140943004: Implement support for non-scale/translate CTM in image filters. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix layer reference Created 5 years, 7 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
« no previous file with comments | « include/core/SkCanvas.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 values: they reflect the top of the save stack, but translated and clipped 108 values: they reflect the top of the save stack, but translated and clipped
109 by the device's XY offset and bitmap-bounds. 109 by the device's XY offset and bitmap-bounds.
110 */ 110 */
111 struct DeviceCM { 111 struct DeviceCM {
112 DeviceCM* fNext; 112 DeviceCM* fNext;
113 SkBaseDevice* fDevice; 113 SkBaseDevice* fDevice;
114 SkRasterClip fClip; 114 SkRasterClip fClip;
115 SkPaint* fPaint; // may be null (in the future) 115 SkPaint* fPaint; // may be null (in the future)
116 const SkMatrix* fMatrix; 116 const SkMatrix* fMatrix;
117 SkMatrix fMatrixStorage; 117 SkMatrix fMatrixStorage;
118 SkMatrix fStashedMatrix; // Original CTM; used by imageFilter at saveLayer time
118 const bool fDeviceIsBitmapDevice; 119 const bool fDeviceIsBitmapDevice;
119 120
120 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 121 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
121 bool conservativeRasterClip, bool deviceIsBitmapDevice) 122 bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMat rix& stashed)
122 : fNext(NULL) 123 : fNext(NULL)
123 , fClip(conservativeRasterClip) 124 , fClip(conservativeRasterClip)
125 , fStashedMatrix(stashed)
124 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 126 , fDeviceIsBitmapDevice(deviceIsBitmapDevice)
125 { 127 {
126 if (NULL != device) { 128 if (NULL != device) {
127 device->ref(); 129 device->ref();
128 device->onAttachToCanvas(canvas); 130 device->onAttachToCanvas(canvas);
129 } 131 }
130 fDevice = device; 132 fDevice = device;
131 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 133 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
132 } 134 }
133 135
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 fSaveCount = 1; 523 fSaveCount = 1;
522 fMetaData = NULL; 524 fMetaData = NULL;
523 525
524 fClipStack.reset(SkNEW(SkClipStack)); 526 fClipStack.reset(SkNEW(SkClipStack));
525 527
526 fMCRec = (MCRec*)fMCStack.push_back(); 528 fMCRec = (MCRec*)fMCStack.push_back();
527 new (fMCRec) MCRec(fConservativeRasterClip); 529 new (fMCRec) MCRec(fConservativeRasterClip);
528 530
529 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 531 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
530 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 532 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
531 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f alse); 533 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f alse,
534 fMCRec->fMatrix);
532 535
533 fMCRec->fTopLayer = fMCRec->fLayer; 536 fMCRec->fTopLayer = fMCRec->fLayer;
534 537
535 fSurfaceBase = NULL; 538 fSurfaceBase = NULL;
536 539
537 if (device) { 540 if (device) {
538 device->initForRootLayer(fProps.pixelGeometry()); 541 device->initForRootLayer(fProps.pixelGeometry());
539 if (device->forceConservativeRasterClip()) { 542 if (device->forceConservativeRasterClip()) {
540 fConservativeRasterClip = true; 543 fConservativeRasterClip = true;
541 } 544 }
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 fSaveCount += 1; 987 fSaveCount += 1;
985 this->internalSaveLayer(bounds, paint, flags, strategy); 988 this->internalSaveLayer(bounds, paint, flags, strategy);
986 return this->getSaveCount() - 1; 989 return this->getSaveCount() - 1;
987 } 990 }
988 991
989 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 992 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags,
990 SaveLayerStrategy strategy) { 993 SaveLayerStrategy strategy) {
991 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 994 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
992 flags |= kClipToLayer_SaveFlag; 995 flags |= kClipToLayer_SaveFlag;
993 #endif 996 #endif
997 SkLazyPaint lazyP;
998 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL;
999 SkMatrix stashedMatrix = fMCRec->fMatrix;
1000 SkMatrix remainder;
1001 SkSize scale;
1002 if (imageFilter &&
1003 !stashedMatrix.isScaleTranslate() && stashedMatrix.decomposeScale(&scale , &remainder)) {
1004 // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix
1005 this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height( )));
1006 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt er(
1007 remainder, SkFilterQuality::kLow_SkFilterQua lity, imageFilter));
1008 imageFilter = matrixFilter.get();
1009 SkPaint* p = lazyP.set(*paint);
1010 p->setImageFilter(imageFilter);
1011 paint = p;
1012 }
994 1013
995 // do this before we create the layer. We don't call the public save() since 1014 // do this before we create the layer. We don't call the public save() since
996 // that would invoke a possibly overridden virtual 1015 // that would invoke a possibly overridden virtual
997 this->internalSave(); 1016 this->internalSave();
998 1017
999 fDeviceCMDirty = true; 1018 fDeviceCMDirty = true;
1000 1019
1001 SkIRect ir; 1020 SkIRect ir;
1002 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : NULL)) { 1021 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) {
1003 return; 1022 return;
1004 } 1023 }
1005 1024
1006 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1025 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
1007 // the clipRectBounds() call above? 1026 // the clipRectBounds() call above?
1008 if (kNoLayer_SaveLayerStrategy == strategy) { 1027 if (kNoLayer_SaveLayerStrategy == strategy) {
1009 return; 1028 return;
1010 } 1029 }
1011 1030
1012 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 1031 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
(...skipping 27 matching lines...) Expand all
1040 "Unable to create device for layer.") ; 1059 "Unable to create device for layer.") ;
1041 return; 1060 return;
1042 } 1061 }
1043 forceSpriteOnRestore = true; 1062 forceSpriteOnRestore = true;
1044 } 1063 }
1045 device = newDev; 1064 device = newDev;
1046 } 1065 }
1047 1066
1048 device->setOrigin(ir.fLeft, ir.fTop); 1067 device->setOrigin(ir.fLeft, ir.fTop);
1049 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip, 1068 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip,
1050 forceSpriteOnRestore)); 1069 forceSpriteOnRestore, stashedMatrix) );
1051 device->unref(); 1070 device->unref();
1052 1071
1053 layer->fNext = fMCRec->fTopLayer; 1072 layer->fNext = fMCRec->fTopLayer;
1054 fMCRec->fLayer = layer; 1073 fMCRec->fLayer = layer;
1055 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1074 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
1056 } 1075 }
1057 1076
1058 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1077 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
1059 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1078 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag);
1060 } 1079 }
(...skipping 29 matching lines...) Expand all
1090 1109
1091 /* Time to draw the layer's offscreen. We can't call the public drawSprite, 1110 /* Time to draw the layer's offscreen. We can't call the public drawSprite,
1092 since if we're being recorded, we don't want to record this (the 1111 since if we're being recorded, we don't want to record this (the
1093 recorder will have already recorded the restore). 1112 recorder will have already recorded the restore).
1094 */ 1113 */
1095 if (layer) { 1114 if (layer) {
1096 if (layer->fNext) { 1115 if (layer->fNext) {
1097 const SkIPoint& origin = layer->fDevice->getOrigin(); 1116 const SkIPoint& origin = layer->fDevice->getOrigin();
1098 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1117 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1099 layer->fPaint, layer->fDeviceIsBitmapDevice ); 1118 layer->fPaint, layer->fDeviceIsBitmapDevice );
1119 // restore what we smashed in internalSaveLayer
1120 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'
1100 // reset this, since internalDrawDevice will have set it to true 1121 // reset this, since internalDrawDevice will have set it to true
1101 fDeviceCMDirty = true; 1122 fDeviceCMDirty = true;
1102 SkDELETE(layer); 1123 SkDELETE(layer);
1103 } else { 1124 } else {
1104 // we're at the root 1125 // we're at the root
1105 SkASSERT(layer == (void*)fDeviceCMStorage); 1126 SkASSERT(layer == (void*)fDeviceCMStorage);
1106 layer->~DeviceCM(); 1127 layer->~DeviceCM();
1128 // no need to update fMCRec, 'cause we're killing the canvas
1107 } 1129 }
1108 } 1130 }
1109 } 1131 }
1110 1132
1111 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1133 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
1112 if (NULL == props) { 1134 if (NULL == props) {
1113 props = &fProps; 1135 props = &fProps;
1114 } 1136 }
1115 return this->onNewSurface(info, *props); 1137 return this->onNewSurface(info, *props);
1116 } 1138 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 } 1347 }
1326 1348
1327 this->checkForDeferredSave(); 1349 this->checkForDeferredSave();
1328 fDeviceCMDirty = true; 1350 fDeviceCMDirty = true;
1329 fCachedLocalClipBoundsDirty = true; 1351 fCachedLocalClipBoundsDirty = true;
1330 fMCRec->fMatrix.preConcat(matrix); 1352 fMCRec->fMatrix.preConcat(matrix);
1331 1353
1332 this->didConcat(matrix); 1354 this->didConcat(matrix);
1333 } 1355 }
1334 1356
1357 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
1358 fDeviceCMDirty = true;
1359 fCachedLocalClipBoundsDirty = true;
1360 fMCRec->fMatrix = matrix;
1361 }
1362
1335 void SkCanvas::setMatrix(const SkMatrix& matrix) { 1363 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1336 this->checkForDeferredSave(); 1364 this->checkForDeferredSave();
1337 fDeviceCMDirty = true; 1365 this->internalSetMatrix(matrix);
1338 fCachedLocalClipBoundsDirty = true;
1339 fMCRec->fMatrix = matrix;
1340 this->didSetMatrix(matrix); 1366 this->didSetMatrix(matrix);
1341 } 1367 }
1342 1368
1343 void SkCanvas::resetMatrix() { 1369 void SkCanvas::resetMatrix() {
1344 SkMatrix matrix; 1370 SkMatrix matrix;
1345 1371
1346 matrix.reset(); 1372 matrix.reset();
1347 this->setMatrix(matrix); 1373 this->setMatrix(matrix);
1348 } 1374 }
1349 1375
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 } 2713 }
2688 2714
2689 if (matrix) { 2715 if (matrix) {
2690 canvas->concat(*matrix); 2716 canvas->concat(*matrix);
2691 } 2717 }
2692 } 2718 }
2693 2719
2694 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2720 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2695 fCanvas->restoreToCount(fSaveCount); 2721 fCanvas->restoreToCount(fSaveCount);
2696 } 2722 }
OLDNEW
« no previous file with comments | « include/core/SkCanvas.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698