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

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

Issue 986623003: Implement support for non-scale/translate CTM in image filters. Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update to TOT Created 5 years, 4 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 "SkBitmapDevice.h" 8 #include "SkBitmapDevice.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 10 #include "SkCanvasPriv.h"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 by the device's XY offset and bitmap-bounds. 184 by the device's XY offset and bitmap-bounds.
185 */ 185 */
186 struct DeviceCM { 186 struct DeviceCM {
187 DeviceCM* fNext; 187 DeviceCM* fNext;
188 SkBaseDevice* fDevice; 188 SkBaseDevice* fDevice;
189 SkRasterClip fClip; 189 SkRasterClip fClip;
190 SkPaint* fPaint; // may be null (in the future) 190 SkPaint* fPaint; // may be null (in the future)
191 const SkMatrix* fMatrix; 191 const SkMatrix* fMatrix;
192 SkMatrix fMatrixStorage; 192 SkMatrix fMatrixStorage;
193 const bool fDeviceIsBitmapDevice; 193 const bool fDeviceIsBitmapDevice;
194 SkMatrix fStashedMatrix; // Original CTM; used by imageFilter at saveLayer time
194 195
195 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 196 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
196 bool conservativeRasterClip, bool deviceIsBitmapDevice) 197 bool conservativeRasterClip, bool deviceIsBitmapDevice,
198 const SkMatrix& stashedMatrix)
197 : fNext(NULL) 199 : fNext(NULL)
198 , fClip(conservativeRasterClip) 200 , fClip(conservativeRasterClip)
199 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 201 , fDeviceIsBitmapDevice(deviceIsBitmapDevice)
202 , fStashedMatrix(stashedMatrix)
200 { 203 {
201 if (NULL != device) { 204 if (NULL != device) {
202 device->ref(); 205 device->ref();
203 device->onAttachToCanvas(canvas); 206 device->onAttachToCanvas(canvas);
204 } 207 }
205 fDevice = device; 208 fDevice = device;
206 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 209 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
207 } 210 }
208 211
209 ~DeviceCM() { 212 ~DeviceCM() {
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 fSaveCount = 1; 607 fSaveCount = 1;
605 fMetaData = NULL; 608 fMetaData = NULL;
606 609
607 fClipStack.reset(SkNEW(SkClipStack)); 610 fClipStack.reset(SkNEW(SkClipStack));
608 611
609 fMCRec = (MCRec*)fMCStack.push_back(); 612 fMCRec = (MCRec*)fMCStack.push_back();
610 new (fMCRec) MCRec(fConservativeRasterClip); 613 new (fMCRec) MCRec(fConservativeRasterClip);
611 614
612 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 615 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
613 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 616 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
614 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f alse); 617 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f alse,
618 fMCRec->fMatrix);
615 619
616 fMCRec->fTopLayer = fMCRec->fLayer; 620 fMCRec->fTopLayer = fMCRec->fLayer;
617 621
618 fSurfaceBase = NULL; 622 fSurfaceBase = NULL;
619 623
620 if (device) { 624 if (device) {
621 // The root device and the canvas should always have the same pixel geom etry 625 // The root device and the canvas should always have the same pixel geom etry
622 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( )); 626 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( ));
623 if (device->forceConservativeRasterClip()) { 627 if (device->forceConservativeRasterClip()) {
624 fConservativeRasterClip = true; 628 fConservativeRasterClip = true;
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 fSaveCount += 1; 1076 fSaveCount += 1;
1073 this->internalSaveLayer(bounds, paint, flags, strategy); 1077 this->internalSaveLayer(bounds, paint, flags, strategy);
1074 return this->getSaveCount() - 1; 1078 return this->getSaveCount() - 1;
1075 } 1079 }
1076 1080
1077 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 1081 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags,
1078 SaveLayerStrategy strategy) { 1082 SaveLayerStrategy strategy) {
1079 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 1083 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
1080 flags |= kClipToLayer_SaveFlag; 1084 flags |= kClipToLayer_SaveFlag;
1081 #endif 1085 #endif
1086 SkLazyPaint lazyP;
1087 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL;
1088 SkMatrix matrix = fMCRec->fMatrix;
1089 SkMatrix remainder;
1090 SkSize scale;
1091 if (imageFilter && !matrix.isScaleTranslate() && matrix.decomposeScale(&scal e, &remainder)) {
1092 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height() );
1093 this->internalSetMatrix(scaleMatrix);
1094 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt er(remainder, SkFilterQuality::kLow_SkFilterQuality, imageFilter));
1095 imageFilter = matrixFilter.get();
1096 SkPaint* p = lazyP.set(*paint);
1097 p->setImageFilter(imageFilter);
1098 paint = p;
1099 }
1082 1100
1083 // do this before we create the layer. We don't call the public save() since 1101 // do this before we create the layer. We don't call the public save() since
1084 // that would invoke a possibly overridden virtual 1102 // that would invoke a possibly overridden virtual
1085 this->internalSave(); 1103 this->internalSave();
1086 1104
1087 fDeviceCMDirty = true; 1105 fDeviceCMDirty = true;
1088 1106
1089 SkIRect ir; 1107 SkIRect ir;
1090 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : NULL)) { 1108 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) {
1091 return; 1109 return;
1092 } 1110 }
1093 1111
1094 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1112 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
1095 // the clipRectBounds() call above? 1113 // the clipRectBounds() call above?
1096 if (kNoLayer_SaveLayerStrategy == strategy) { 1114 if (kNoLayer_SaveLayerStrategy == strategy) {
1097 return; 1115 return;
1098 } 1116 }
1099 1117
1100 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 1118 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
(...skipping 28 matching lines...) Expand all
1129 "Unable to create device for layer.") ; 1147 "Unable to create device for layer.") ;
1130 return; 1148 return;
1131 } 1149 }
1132 forceSpriteOnRestore = true; 1150 forceSpriteOnRestore = true;
1133 } 1151 }
1134 device = newDev; 1152 device = newDev;
1135 } 1153 }
1136 1154
1137 device->setOrigin(ir.fLeft, ir.fTop); 1155 device->setOrigin(ir.fLeft, ir.fTop);
1138 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip, 1156 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip,
1139 forceSpriteOnRestore)); 1157 forceSpriteOnRestore, fMCRec->fMatri x));
1140 device->unref(); 1158 device->unref();
1141 1159
1142 layer->fNext = fMCRec->fTopLayer; 1160 layer->fNext = fMCRec->fTopLayer;
1143 fMCRec->fLayer = layer; 1161 fMCRec->fLayer = layer;
1144 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1162 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
1145 } 1163 }
1146 1164
1147 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1165 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
1148 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1166 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag);
1149 } 1167 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 since if we're being recorded, we don't want to record this (the 1199 since if we're being recorded, we don't want to record this (the
1182 recorder will have already recorded the restore). 1200 recorder will have already recorded the restore).
1183 */ 1201 */
1184 if (layer) { 1202 if (layer) {
1185 if (layer->fNext) { 1203 if (layer->fNext) {
1186 const SkIPoint& origin = layer->fDevice->getOrigin(); 1204 const SkIPoint& origin = layer->fDevice->getOrigin();
1187 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1205 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1188 layer->fPaint, layer->fDeviceIsBitmapDevice ); 1206 layer->fPaint, layer->fDeviceIsBitmapDevice );
1189 // reset this, since internalDrawDevice will have set it to true 1207 // reset this, since internalDrawDevice will have set it to true
1190 fDeviceCMDirty = true; 1208 fDeviceCMDirty = true;
1209 if (fMCRec) {
1210 fMCRec->fMatrix = layer->fStashedMatrix;
1211 }
1191 SkDELETE(layer); 1212 SkDELETE(layer);
1192 } else { 1213 } else {
1193 // we're at the root 1214 // we're at the root
1194 SkASSERT(layer == (void*)fDeviceCMStorage); 1215 SkASSERT(layer == (void*)fDeviceCMStorage);
1195 layer->~DeviceCM(); 1216 layer->~DeviceCM();
1196 } 1217 }
1197 } 1218 }
1198 } 1219 }
1199 1220
1200 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1221 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 } 1454 }
1434 1455
1435 this->checkForDeferredSave(); 1456 this->checkForDeferredSave();
1436 fDeviceCMDirty = true; 1457 fDeviceCMDirty = true;
1437 fCachedLocalClipBoundsDirty = true; 1458 fCachedLocalClipBoundsDirty = true;
1438 fMCRec->fMatrix.preConcat(matrix); 1459 fMCRec->fMatrix.preConcat(matrix);
1439 1460
1440 this->didConcat(matrix); 1461 this->didConcat(matrix);
1441 } 1462 }
1442 1463
1464 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
1465 fDeviceCMDirty = true;
1466 fCachedLocalClipBoundsDirty = true;
1467 fMCRec->fMatrix = matrix;
1468 }
1469
1443 void SkCanvas::setMatrix(const SkMatrix& matrix) { 1470 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1444 this->checkForDeferredSave(); 1471 this->checkForDeferredSave();
1445 fDeviceCMDirty = true; 1472 this->internalSetMatrix(matrix);
1446 fCachedLocalClipBoundsDirty = true;
1447 fMCRec->fMatrix = matrix;
1448 this->didSetMatrix(matrix); 1473 this->didSetMatrix(matrix);
1449 } 1474 }
1450 1475
1451 void SkCanvas::resetMatrix() { 1476 void SkCanvas::resetMatrix() {
1452 SkMatrix matrix; 1477 SkMatrix matrix;
1453 1478
1454 matrix.reset(); 1479 matrix.reset();
1455 this->setMatrix(matrix); 1480 this->setMatrix(matrix);
1456 } 1481 }
1457 1482
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 } 2922 }
2898 2923
2899 if (matrix) { 2924 if (matrix) {
2900 canvas->concat(*matrix); 2925 canvas->concat(*matrix);
2901 } 2926 }
2902 } 2927 }
2903 2928
2904 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2929 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2905 fCanvas->restoreToCount(fSaveCount); 2930 fCanvas->restoreToCount(fSaveCount);
2906 } 2931 }
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