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

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

Issue 1120043002: Implement support for non-scale/translate CTM in image filters. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 );
1100 // reset this, since internalDrawDevice will have set it to true 1119 // reset this, since internalDrawDevice will have set it to true
1101 fDeviceCMDirty = true; 1120 fDeviceCMDirty = true;
1102 SkDELETE(layer); 1121 SkDELETE(layer);
1103 } else { 1122 } else {
1104 // we're at the root 1123 // we're at the root
1105 SkASSERT(layer == (void*)fDeviceCMStorage); 1124 SkASSERT(layer == (void*)fDeviceCMStorage);
1106 layer->~DeviceCM(); 1125 layer->~DeviceCM();
1107 } 1126 }
1127 if (fMCRec) {
1128 // restore what we smashed in internalSaveLayer
1129 fMCRec->fMatrix = layer->fStashedMatrix;
1130 }
1108 } 1131 }
1109 } 1132 }
1110 1133
1111 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1134 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
1112 if (NULL == props) { 1135 if (NULL == props) {
1113 props = &fProps; 1136 props = &fProps;
1114 } 1137 }
1115 return this->onNewSurface(info, *props); 1138 return this->onNewSurface(info, *props);
1116 } 1139 }
1117 1140
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 } 1348 }
1326 1349
1327 this->checkForDeferredSave(); 1350 this->checkForDeferredSave();
1328 fDeviceCMDirty = true; 1351 fDeviceCMDirty = true;
1329 fCachedLocalClipBoundsDirty = true; 1352 fCachedLocalClipBoundsDirty = true;
1330 fMCRec->fMatrix.preConcat(matrix); 1353 fMCRec->fMatrix.preConcat(matrix);
1331 1354
1332 this->didConcat(matrix); 1355 this->didConcat(matrix);
1333 } 1356 }
1334 1357
1358 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
1359 fDeviceCMDirty = true;
1360 fCachedLocalClipBoundsDirty = true;
1361 fMCRec->fMatrix = matrix;
1362 }
1363
1335 void SkCanvas::setMatrix(const SkMatrix& matrix) { 1364 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1336 this->checkForDeferredSave(); 1365 this->checkForDeferredSave();
1337 fDeviceCMDirty = true; 1366 this->internalSetMatrix(matrix);
1338 fCachedLocalClipBoundsDirty = true;
1339 fMCRec->fMatrix = matrix;
1340 this->didSetMatrix(matrix); 1367 this->didSetMatrix(matrix);
1341 } 1368 }
1342 1369
1343 void SkCanvas::resetMatrix() { 1370 void SkCanvas::resetMatrix() {
1344 SkMatrix matrix; 1371 SkMatrix matrix;
1345 1372
1346 matrix.reset(); 1373 matrix.reset();
1347 this->setMatrix(matrix); 1374 this->setMatrix(matrix);
1348 } 1375 }
1349 1376
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 } 2714 }
2688 2715
2689 if (matrix) { 2716 if (matrix) {
2690 canvas->concat(*matrix); 2717 canvas->concat(*matrix);
2691 } 2718 }
2692 } 2719 }
2693 2720
2694 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2721 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2695 fCanvas->restoreToCount(fSaveCount); 2722 fCanvas->restoreToCount(fSaveCount);
2696 } 2723 }
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