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

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 latest rev of SkMatrixImageFilter move Created 5 years, 9 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
« gm/imagefilterstransformed.cpp ('K') | « gyp/gmslides.gypi ('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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 stack. Whenever the canvas changes, it marks a dirty flag, and then before 105 stack. Whenever the canvas changes, it marks a dirty flag, and then before
106 these are used (assuming we're not on a layer) we rebuild these cache 106 these are used (assuming we're not on a layer) we rebuild these cache
107 values: they reflect the top of the save stack, but translated and clipped 107 values: they reflect the top of the save stack, but translated and clipped
108 by the device's XY offset and bitmap-bounds. 108 by the device's XY offset and bitmap-bounds.
109 */ 109 */
110 struct DeviceCM { 110 struct DeviceCM {
111 DeviceCM* fNext; 111 DeviceCM* fNext;
112 SkBaseDevice* fDevice; 112 SkBaseDevice* fDevice;
113 SkRasterClip fClip; 113 SkRasterClip fClip;
114 const SkMatrix* fMatrix; 114 const SkMatrix* fMatrix;
115 SkPaint* fPaint; // may be null (in the future) 115 SkPaint* fPaint; // may be null (in the future)
robertphillips 2015/03/20 14:01:10 // The stashed matrix is used for ... ?
116 SkMatrix fStashedMatrix;
116 117
117 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 118 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
118 bool conservativeRasterClip) 119 bool conservativeRasterClip, const SkMatrix& stashedMatrix)
119 : fNext(NULL) 120 : fNext(NULL)
120 , fClip(conservativeRasterClip) 121 , fClip(conservativeRasterClip)
122 , fStashedMatrix(stashedMatrix)
121 { 123 {
122 if (NULL != device) { 124 if (NULL != device) {
123 device->ref(); 125 device->ref();
124 device->onAttachToCanvas(canvas); 126 device->onAttachToCanvas(canvas);
125 } 127 }
126 fDevice = device; 128 fDevice = device;
127 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 129 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
128 } 130 }
129 131
130 ~DeviceCM() { 132 ~DeviceCM() {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 fCachedLocalClipBounds.setEmpty(); 432 fCachedLocalClipBounds.setEmpty();
431 fCachedLocalClipBoundsDirty = true; 433 fCachedLocalClipBoundsDirty = true;
432 fAllowSoftClip = true; 434 fAllowSoftClip = true;
433 fAllowSimplifyClip = false; 435 fAllowSimplifyClip = false;
434 fDeviceCMDirty = true; 436 fDeviceCMDirty = true;
435 fSaveCount = 1; 437 fSaveCount = 1;
436 fMetaData = NULL; 438 fMetaData = NULL;
437 439
438 fMCRec = (MCRec*)fMCStack.push_back(); 440 fMCRec = (MCRec*)fMCStack.push_back();
439 new (fMCRec) MCRec(fConservativeRasterClip); 441 new (fMCRec) MCRec(fConservativeRasterClip);
440 442
robertphillips 2015/03/20 14:01:09 overlength ?
Stephen White 2015/03/20 14:47:21 Done.
441 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip)); 443 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip, fMCRec->fMatrix));
442 fMCRec->fTopLayer = fMCRec->fLayer; 444 fMCRec->fTopLayer = fMCRec->fLayer;
443 445
444 fSurfaceBase = NULL; 446 fSurfaceBase = NULL;
445 447
446 fClipStack.reset(SkNEW(SkClipStack)); 448 fClipStack.reset(SkNEW(SkClipStack));
447 449
448 if (device) { 450 if (device) {
449 device->initForRootLayer(fProps.pixelGeometry()); 451 device->initForRootLayer(fProps.pixelGeometry());
450 if (device->forceConservativeRasterClip()) { 452 if (device->forceConservativeRasterClip()) {
451 fConservativeRasterClip = true; 453 fConservativeRasterClip = true;
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 fSaveCount += 1; 894 fSaveCount += 1;
893 this->internalSaveLayer(bounds, paint, flags, strategy); 895 this->internalSaveLayer(bounds, paint, flags, strategy);
894 return this->getSaveCount() - 1; 896 return this->getSaveCount() - 1;
895 } 897 }
896 898
897 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 899 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags,
898 SaveLayerStrategy strategy) { 900 SaveLayerStrategy strategy) {
899 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 901 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
900 flags |= kClipToLayer_SaveFlag; 902 flags |= kClipToLayer_SaveFlag;
901 #endif 903 #endif
904 SkLazyPaint lazyP;
905 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL;
robertphillips 2015/03/20 14:01:09 Can matrix be a "const&" rather than a copy ?
Stephen White 2015/03/20 14:47:21 No. fMCRec->fMatrix will be modified by resetMatri
906 SkMatrix matrix = fMCRec->fMatrix;
907 SkMatrix remainder;
908 SkSize scale;
909 if (imageFilter && !matrix.isScaleTranslate() && matrix.decomposeScale(&scal e, &remainder)) {
910 this->resetMatrix();
911 this->scale(scale.width(), scale.height());
912 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt er(remainder, SkFilterQuality::kHigh_SkFilterQuality, imageFilter));
913 imageFilter = matrixFilter.get();
914 SkPaint* p = lazyP.set(*paint);
915 p->setImageFilter(imageFilter);
916 paint = p;
917 }
902 918
903 // do this before we create the layer. We don't call the public save() since 919 // do this before we create the layer. We don't call the public save() since
904 // that would invoke a possibly overridden virtual 920 // that would invoke a possibly overridden virtual
905 this->internalSave(); 921 this->internalSave();
906 922
907 fDeviceCMDirty = true; 923 fDeviceCMDirty = true;
908 924
909 SkIRect ir; 925 SkIRect ir;
910 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : NULL)) { 926 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) {
911 return; 927 return;
912 } 928 }
913 929
914 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 930 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
915 // the clipRectBounds() call above? 931 // the clipRectBounds() call above?
916 if (kNoLayer_SaveLayerStrategy == strategy) { 932 if (kNoLayer_SaveLayerStrategy == strategy) {
917 return; 933 return;
918 } 934 }
919 935
920 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 936 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
(...skipping 23 matching lines...) Expand all
944 #endif 960 #endif
945 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, fProps .pixelGeometry()), 961 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, fProps .pixelGeometry()),
946 paint); 962 paint);
947 if (NULL == device) { 963 if (NULL == device) {
948 SkErrorInternals::SetError( kInternalError_SkError, 964 SkErrorInternals::SetError( kInternalError_SkError,
949 "Unable to create device for layer."); 965 "Unable to create device for layer.");
950 return; 966 return;
951 } 967 }
952 968
953 device->setOrigin(ir.fLeft, ir.fTop); 969 device->setOrigin(ir.fLeft, ir.fTop);
954 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip)); 970 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip, matrix));
955 device->unref(); 971 device->unref();
956 972
957 layer->fNext = fMCRec->fTopLayer; 973 layer->fNext = fMCRec->fTopLayer;
958 fMCRec->fLayer = layer; 974 fMCRec->fLayer = layer;
959 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 975 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
960 } 976 }
961 977
962 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 978 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
963 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 979 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag);
964 } 980 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 recorder will have already recorded the restore). 1013 recorder will have already recorded the restore).
998 */ 1014 */
999 if (layer) { 1015 if (layer) {
1000 if (layer->fNext) { 1016 if (layer->fNext) {
1001 const SkIPoint& origin = layer->fDevice->getOrigin(); 1017 const SkIPoint& origin = layer->fDevice->getOrigin();
1002 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1018 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1003 layer->fPaint); 1019 layer->fPaint);
1004 // reset this, since internalDrawDevice will have set it to true 1020 // reset this, since internalDrawDevice will have set it to true
1005 fDeviceCMDirty = true; 1021 fDeviceCMDirty = true;
1006 } 1022 }
1023 if (layer->fPaint && layer->fPaint->fImageFilter) {
1024 fMCRec->fMatrix = layer->fStashedMatrix;
1025 }
1007 SkDELETE(layer); 1026 SkDELETE(layer);
1008 } 1027 }
1009 } 1028 }
1010 1029
1011 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1030 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
1012 if (NULL == props) { 1031 if (NULL == props) {
1013 props = &fProps; 1032 props = &fProps;
1014 } 1033 }
1015 return this->onNewSurface(info, *props); 1034 return this->onNewSurface(info, *props);
1016 } 1035 }
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 } 2538 }
2520 2539
2521 if (matrix) { 2540 if (matrix) {
2522 canvas->concat(*matrix); 2541 canvas->concat(*matrix);
2523 } 2542 }
2524 } 2543 }
2525 2544
2526 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2545 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2527 fCanvas->restoreToCount(fSaveCount); 2546 fCanvas->restoreToCount(fSaveCount);
2528 } 2547 }
OLDNEW
« gm/imagefilterstransformed.cpp ('K') | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698