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

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

Issue 1899263002: post apply non-scale transforms after imagefilters have run (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: removed troublesome aa parameter (that was added earlier) Created 4 years, 8 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/SkImageFilter.h ('k') | src/core/SkMatrixImageFilter.cpp » ('j') | 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 values: they reflect the top of the save stack, but translated and clipped 189 values: they reflect the top of the save stack, but translated and clipped
190 by the device's XY offset and bitmap-bounds. 190 by the device's XY offset and bitmap-bounds.
191 */ 191 */
192 struct DeviceCM { 192 struct DeviceCM {
193 DeviceCM* fNext; 193 DeviceCM* fNext;
194 SkBaseDevice* fDevice; 194 SkBaseDevice* fDevice;
195 SkRasterClip fClip; 195 SkRasterClip fClip;
196 SkPaint* fPaint; // may be null (in the future) 196 SkPaint* fPaint; // may be null (in the future)
197 const SkMatrix* fMatrix; 197 const SkMatrix* fMatrix;
198 SkMatrix fMatrixStorage; 198 SkMatrix fMatrixStorage;
199 SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
199 const bool fDeviceIsBitmapDevice; 200 const bool fDeviceIsBitmapDevice;
200 201
201 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 202 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
202 bool conservativeRasterClip, bool deviceIsBitmapDevice) 203 bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMat rix& stashed)
203 : fNext(nullptr) 204 : fNext(nullptr)
204 , fClip(conservativeRasterClip) 205 , fClip(conservativeRasterClip)
206 , fStashedMatrix(stashed)
205 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 207 , fDeviceIsBitmapDevice(deviceIsBitmapDevice)
206 { 208 {
207 if (nullptr != device) { 209 if (nullptr != device) {
208 device->ref(); 210 device->ref();
209 device->onAttachToCanvas(canvas); 211 device->onAttachToCanvas(canvas);
210 } 212 }
211 fDevice = device; 213 fDevice = device;
212 fPaint = paint ? new SkPaint(*paint) : nullptr; 214 fPaint = paint ? new SkPaint(*paint) : nullptr;
213 } 215 }
214 216
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 fSaveCount = 1; 659 fSaveCount = 1;
658 fMetaData = nullptr; 660 fMetaData = nullptr;
659 661
660 fClipStack.reset(new SkClipStack); 662 fClipStack.reset(new SkClipStack);
661 663
662 fMCRec = (MCRec*)fMCStack.push_back(); 664 fMCRec = (MCRec*)fMCStack.push_back();
663 new (fMCRec) MCRec(fConservativeRasterClip); 665 new (fMCRec) MCRec(fConservativeRasterClip);
664 666
665 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 667 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
666 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 668 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
667 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast erClip, false); 669 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast erClip, false,
670 fMCRec->fMatrix);
668 671
669 fMCRec->fTopLayer = fMCRec->fLayer; 672 fMCRec->fTopLayer = fMCRec->fLayer;
670 673
671 fSurfaceBase = nullptr; 674 fSurfaceBase = nullptr;
672 675
673 if (device) { 676 if (device) {
674 // The root device and the canvas should always have the same pixel geom etry 677 // The root device and the canvas should always have the same pixel geom etry
675 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( )); 678 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry( ));
676 device->onAttachToCanvas(this); 679 device->onAttachToCanvas(this);
677 fMCRec->fLayer->fDevice = SkRef(device); 680 fMCRec->fLayer->fDevice = SkRef(device);
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 1189
1187 void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra tegy) { 1190 void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra tegy) {
1188 const SkRect* bounds = rec.fBounds; 1191 const SkRect* bounds = rec.fBounds;
1189 const SkPaint* paint = rec.fPaint; 1192 const SkPaint* paint = rec.fPaint;
1190 SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 1193 SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags;
1191 1194
1192 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 1195 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
1193 saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag; 1196 saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag;
1194 #endif 1197 #endif
1195 1198
1199 SkLazyPaint lazyP;
1200 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL;
1201 SkMatrix stashedMatrix = fMCRec->fMatrix;
1202 #ifndef SK_SUPPORT_LEGACY_IMAGEFILTER_CTM
1203 SkMatrix remainder;
1204 SkSize scale;
1205 /*
1206 * ImageFilters (so far) do not correctly handle matrices (CTM) that contai n rotation/skew/etc.
1207 * but they do handle scaling. To accommodate this, we do the following:
1208 *
1209 * 1. Stash off the current CTM
1210 * 2. Decompose the CTM into SCALE and REMAINDER
1211 * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a Matrix ImageFilter that
1212 * contains the REMAINDER
1213 * 4. Proceed as usual, allowing the client to draw into the layer (now wit h a scale-only CTM)
1214 * 5. During restore, we process the MatrixImageFilter, which applies REMAI NDER to the output
1215 * of the original imagefilter, and draw that (via drawSprite)
1216 * 6. Unwack the CTM to its original state (i.e. stashedMatrix)
1217 *
1218 * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer
1219 * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFil ter.
1220 */
1221 if (imageFilter &&
1222 !stashedMatrix.isScaleTranslate() &&
1223 stashedMatrix.decomposeScale(&scale, &remainder))
1224 {
1225 // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix
1226 this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height( )));
1227 SkPaint* p = lazyP.set(*paint);
1228 p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder,
1229 SkFilterQuality::kLow_ SkFilterQuality,
Stephen White 2016/04/20 18:39:34 Blink currently uses High quality in SkiaImageFilt
reed1 2016/04/20 19:42:50 My thinking was that since we decompose the scale,
Stephen White 2016/04/20 21:19:32 OK, let's give it a try.
1230 sk_ref_sp(imageFilter) ));
1231 imageFilter = p->getImageFilter();
1232 paint = p;
1233 }
1234 #endif
1235
1196 // do this before we create the layer. We don't call the public save() since 1236 // do this before we create the layer. We don't call the public save() since
1197 // that would invoke a possibly overridden virtual 1237 // that would invoke a possibly overridden virtual
1198 this->internalSave(); 1238 this->internalSave();
1199 1239
1200 fDeviceCMDirty = true; 1240 fDeviceCMDirty = true;
1201 1241
1202 SkIRect ir; 1242 SkIRect ir;
1203 if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, paint ? paint->getIma geFilter() : nullptr)) { 1243 if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
1204 return; 1244 return;
1205 } 1245 }
1206 1246
1207 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1247 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
1208 // the clipRectBounds() call above? 1248 // the clipRectBounds() call above?
1209 if (kNoLayer_SaveLayerStrategy == strategy) { 1249 if (kNoLayer_SaveLayerStrategy == strategy) {
1210 return; 1250 return;
1211 } 1251 }
1212 1252
1213 bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 1253 bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 forceSpriteOnRestore = true; 1289 forceSpriteOnRestore = true;
1250 } 1290 }
1251 device = newDev; 1291 device = newDev;
1252 } 1292 }
1253 device->setOrigin(ir.fLeft, ir.fTop); 1293 device->setOrigin(ir.fLeft, ir.fTop);
1254 1294
1255 if (rec.fBackdrop) { 1295 if (rec.fBackdrop) {
1256 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic e, fMCRec->fMatrix); 1296 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic e, fMCRec->fMatrix);
1257 } 1297 }
1258 1298
1259 DeviceCM* layer = 1299 DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip,
1260 new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpri teOnRestore); 1300 forceSpriteOnRestore, stashedMatrix);
1261 device->unref(); 1301 device->unref();
1262 1302
1263 layer->fNext = fMCRec->fTopLayer; 1303 layer->fNext = fMCRec->fTopLayer;
1264 fMCRec->fLayer = layer; 1304 fMCRec->fLayer = layer;
1265 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1305 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
1266 } 1306 }
1267 1307
1268 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1308 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
1269 if (0xFF == alpha) { 1309 if (0xFF == alpha) {
1270 return this->saveLayer(bounds, nullptr); 1310 return this->saveLayer(bounds, nullptr);
(...skipping 24 matching lines...) Expand all
1295 1335
1296 /* Time to draw the layer's offscreen. We can't call the public drawSprite, 1336 /* Time to draw the layer's offscreen. We can't call the public drawSprite,
1297 since if we're being recorded, we don't want to record this (the 1337 since if we're being recorded, we don't want to record this (the
1298 recorder will have already recorded the restore). 1338 recorder will have already recorded the restore).
1299 */ 1339 */
1300 if (layer) { 1340 if (layer) {
1301 if (layer->fNext) { 1341 if (layer->fNext) {
1302 const SkIPoint& origin = layer->fDevice->getOrigin(); 1342 const SkIPoint& origin = layer->fDevice->getOrigin();
1303 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1343 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1304 layer->fPaint, layer->fDeviceIsBitmapDevice ); 1344 layer->fPaint, layer->fDeviceIsBitmapDevice );
1345 // restore what we smashed in internalSaveLayer
1346 fMCRec->fMatrix = layer->fStashedMatrix;
1305 // reset this, since internalDrawDevice will have set it to true 1347 // reset this, since internalDrawDevice will have set it to true
1306 fDeviceCMDirty = true; 1348 fDeviceCMDirty = true;
1307 delete layer; 1349 delete layer;
1308 } else { 1350 } else {
1309 // we're at the root 1351 // we're at the root
1310 SkASSERT(layer == (void*)fDeviceCMStorage); 1352 SkASSERT(layer == (void*)fDeviceCMStorage);
1311 layer->~DeviceCM(); 1353 layer->~DeviceCM();
1354 // no need to update fMCRec, 'cause we're killing the canvas
1312 } 1355 }
1313 } 1356 }
1314 } 1357 }
1315 1358
1316 sk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceP rops* props) { 1359 sk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceP rops* props) {
1317 if (nullptr == props) { 1360 if (nullptr == props) {
1318 props = &fProps; 1361 props = &fProps;
1319 } 1362 }
1320 return this->onNewSurface(info, *props); 1363 return this->onNewSurface(info, *props);
1321 } 1364 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 } 1520 }
1478 1521
1479 this->checkForDeferredSave(); 1522 this->checkForDeferredSave();
1480 fDeviceCMDirty = true; 1523 fDeviceCMDirty = true;
1481 fCachedLocalClipBoundsDirty = true; 1524 fCachedLocalClipBoundsDirty = true;
1482 fMCRec->fMatrix.preConcat(matrix); 1525 fMCRec->fMatrix.preConcat(matrix);
1483 1526
1484 this->didConcat(matrix); 1527 this->didConcat(matrix);
1485 } 1528 }
1486 1529
1530 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
1531 fDeviceCMDirty = true;
1532 fCachedLocalClipBoundsDirty = true;
1533 fMCRec->fMatrix = matrix;
1534 }
1535
1487 void SkCanvas::setMatrix(const SkMatrix& matrix) { 1536 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1488 this->checkForDeferredSave(); 1537 this->checkForDeferredSave();
1489 fDeviceCMDirty = true; 1538 this->internalSetMatrix(matrix);
1490 fCachedLocalClipBoundsDirty = true;
1491 fMCRec->fMatrix = matrix;
1492 this->didSetMatrix(matrix); 1539 this->didSetMatrix(matrix);
1493 } 1540 }
1494 1541
1495 void SkCanvas::resetMatrix() { 1542 void SkCanvas::resetMatrix() {
1496 SkMatrix matrix; 1543 this->setMatrix(SkMatrix::I());
1497
1498 matrix.reset();
1499 this->setMatrix(matrix);
1500 } 1544 }
1501 1545
1502 ////////////////////////////////////////////////////////////////////////////// 1546 //////////////////////////////////////////////////////////////////////////////
1503 1547
1504 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 1548 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
1505 this->checkForDeferredSave(); 1549 this->checkForDeferredSave();
1506 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 1550 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1507 this->onClipRect(rect, op, edgeStyle); 1551 this->onClipRect(rect, op, edgeStyle);
1508 } 1552 }
1509 1553
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 3097
3054 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3098 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3055 fCanvas->restoreToCount(fSaveCount); 3099 fCanvas->restoreToCount(fSaveCount);
3056 } 3100 }
3057 3101
3058 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3102 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
3059 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 3103 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
3060 return this->makeSurface(info, props).release(); 3104 return this->makeSurface(info, props).release();
3061 } 3105 }
3062 #endif 3106 #endif
OLDNEW
« no previous file with comments | « include/core/SkImageFilter.h ('k') | src/core/SkMatrixImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698