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

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

Issue 1016483003: First draft of non-scale/translate filters plus blit optimization. Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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
« 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
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)
116 SkMatrix fStashedMatrix;
117 SkMatrix fExtraMatrix;
116 118
117 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 119 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
118 bool conservativeRasterClip) 120 bool conservativeRasterClip, const SkMatrix& stashedMatrix,
121 const SkMatrix& extraMatrix)
119 : fNext(NULL) 122 : fNext(NULL)
120 , fClip(conservativeRasterClip) 123 , fClip(conservativeRasterClip)
124 , fStashedMatrix(stashedMatrix)
125 , fExtraMatrix(extraMatrix)
121 { 126 {
122 if (NULL != device) { 127 if (NULL != device) {
123 device->ref(); 128 device->ref();
124 device->onAttachToCanvas(canvas); 129 device->onAttachToCanvas(canvas);
125 } 130 }
126 fDevice = device; 131 fDevice = device;
127 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 132 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
128 } 133 }
129 134
130 ~DeviceCM() { 135 ~DeviceCM() {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 fCachedLocalClipBoundsDirty = true; 436 fCachedLocalClipBoundsDirty = true;
432 fAllowSoftClip = true; 437 fAllowSoftClip = true;
433 fAllowSimplifyClip = false; 438 fAllowSimplifyClip = false;
434 fDeviceCMDirty = true; 439 fDeviceCMDirty = true;
435 fSaveCount = 1; 440 fSaveCount = 1;
436 fMetaData = NULL; 441 fMetaData = NULL;
437 442
438 fMCRec = (MCRec*)fMCStack.push_back(); 443 fMCRec = (MCRec*)fMCStack.push_back();
439 new (fMCRec) MCRec(fConservativeRasterClip); 444 new (fMCRec) MCRec(fConservativeRasterClip);
440 445
441 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip)); 446 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster Clip, fMCRec->fMatrix, SkMatrix::I()));
442 fMCRec->fTopLayer = fMCRec->fLayer; 447 fMCRec->fTopLayer = fMCRec->fLayer;
443 448
444 fSurfaceBase = NULL; 449 fSurfaceBase = NULL;
445 450
446 fClipStack.reset(SkNEW(SkClipStack)); 451 fClipStack.reset(SkNEW(SkClipStack));
447 452
448 if (device) { 453 if (device) {
449 device->initForRootLayer(fProps.pixelGeometry()); 454 device->initForRootLayer(fProps.pixelGeometry());
450 if (device->forceConservativeRasterClip()) { 455 if (device->forceConservativeRasterClip()) {
451 fConservativeRasterClip = true; 456 fConservativeRasterClip = true;
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 829
825 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 830 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
826 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 831 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
827 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 832 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
828 #else 833 #else
829 return true; 834 return true;
830 #endif 835 #endif
831 } 836 }
832 837
833 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 838 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
834 SkIRect* intersection, const SkImageFilter* imageF ilter) { 839 SkIRect* intersection, const SkImageFilter* imageF ilter,
840 const SkMatrix* shearAndRotateMatrix) {
835 SkIRect clipBounds; 841 SkIRect clipBounds;
836 if (!this->getClipDeviceBounds(&clipBounds)) { 842 if (!this->getClipDeviceBounds(&clipBounds)) {
837 return false; 843 return false;
838 } 844 }
839 845
840 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 846 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix()
841 847
842 if (imageFilter) { 848 if (imageFilter) {
849 if (shearAndRotateMatrix) {
850 SkMatrix shearAndRotateInverse;
851 if (!shearAndRotateMatrix->invert(&shearAndRotateInverse)) {
852 return false;
853 }
854 SkMatrix matrix;
855 if (!ctm.invert(&matrix)) {
856 return false;
857 }
858 matrix.postConcat(shearAndRotateInverse);
859 matrix.postConcat(ctm);
860 SkRect floatBounds;
861 matrix.mapRect(&floatBounds, SkRect::Make(clipBounds));
862 clipBounds = floatBounds.roundOut();
863 }
843 imageFilter->filterBounds(clipBounds, ctm, &clipBounds); 864 imageFilter->filterBounds(clipBounds, ctm, &clipBounds);
844 } 865 }
866
845 SkIRect ir; 867 SkIRect ir;
846 if (bounds) { 868 if (bounds) {
847 SkRect r; 869 SkRect r;
848 870
849 ctm.mapRect(&r, *bounds); 871 ctm.mapRect(&r, *bounds);
850 r.roundOut(&ir); 872 r.roundOut(&ir);
851 // early exit if the layer's bounds are clipped out 873 // early exit if the layer's bounds are clipped out
852 if (!ir.intersect(clipBounds)) { 874 if (!ir.intersect(clipBounds)) {
853 if (bounds_affects_clip(flags)) { 875 if (bounds_affects_clip(flags)) {
854 fCachedLocalClipBoundsDirty = true; 876 fCachedLocalClipBoundsDirty = true;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 fSaveCount += 1; 914 fSaveCount += 1;
893 this->internalSaveLayer(bounds, paint, flags, strategy); 915 this->internalSaveLayer(bounds, paint, flags, strategy);
894 return this->getSaveCount() - 1; 916 return this->getSaveCount() - 1;
895 } 917 }
896 918
897 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 919 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags,
898 SaveLayerStrategy strategy) { 920 SaveLayerStrategy strategy) {
899 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 921 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
900 flags |= kClipToLayer_SaveFlag; 922 flags |= kClipToLayer_SaveFlag;
901 #endif 923 #endif
924 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL;
925 SkMatrix matrix = fMCRec->fMatrix;
926 SkMatrix shearAndRotate = SkMatrix::I();
927 bool doShearAndRotate = false;
928 if (imageFilter && !matrix.isScaleTranslate()) {
929 doShearAndRotate = true;
930 SkMatrix scaleAndTranslate;
931 scaleAndTranslate.setTranslate(matrix.getTranslateX(), matrix.getTransla teY());
932 SkScalar xScale = SkScalarSqrt(matrix[0] * matrix[0] + matrix[3] * matri x[3]);
933 SkScalar yScale = SkScalarSqrt(matrix[1] * matrix[1] + matrix[4] * matri x[4]);
934 scaleAndTranslate.postScale(xScale, yScale);
935 if (!scaleAndTranslate.invert(&shearAndRotate)) {
936 SkASSERT(false);
937 }
938 shearAndRotate.preConcat(matrix);
939 fMCRec->fMatrix = scaleAndTranslate;
940 }
902 941
903 // do this before we create the layer. We don't call the public save() since 942 // do this before we create the layer. We don't call the public save() since
904 // that would invoke a possibly overridden virtual 943 // that would invoke a possibly overridden virtual
905 this->internalSave(); 944 this->internalSave();
906 945
907 fDeviceCMDirty = true; 946 fDeviceCMDirty = true;
908 947
909 SkIRect ir; 948 SkIRect ir;
910 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : NULL)) { 949 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter, doShearAndRotate ? &shearAndRotate : NULL)) {
911 return; 950 return;
912 } 951 }
913 952
914 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 953 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
915 // the clipRectBounds() call above? 954 // the clipRectBounds() call above?
916 if (kNoLayer_SaveLayerStrategy == strategy) { 955 if (kNoLayer_SaveLayerStrategy == strategy) {
917 return; 956 return;
918 } 957 }
919 958
920 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 959 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
(...skipping 23 matching lines...) Expand all
944 #endif 983 #endif
945 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, fProps .pixelGeometry()), 984 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, fProps .pixelGeometry()),
946 paint); 985 paint);
947 if (NULL == device) { 986 if (NULL == device) {
948 SkErrorInternals::SetError( kInternalError_SkError, 987 SkErrorInternals::SetError( kInternalError_SkError,
949 "Unable to create device for layer."); 988 "Unable to create device for layer.");
950 return; 989 return;
951 } 990 }
952 991
953 device->setOrigin(ir.fLeft, ir.fTop); 992 device->setOrigin(ir.fLeft, ir.fTop);
954 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip)); 993 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip, matrix, shearAndRotate));
955 device->unref(); 994 device->unref();
956 995
957 layer->fNext = fMCRec->fTopLayer; 996 layer->fNext = fMCRec->fTopLayer;
958 fMCRec->fLayer = layer; 997 fMCRec->fLayer = layer;
959 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 998 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
960 } 999 }
961 1000
962 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1001 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
963 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1002 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag);
964 } 1003 }
(...skipping 28 matching lines...) Expand all
993 fMCRec = (MCRec*)fMCStack.back(); 1032 fMCRec = (MCRec*)fMCStack.back();
994 1033
995 /* Time to draw the layer's offscreen. We can't call the public drawSprite, 1034 /* Time to draw the layer's offscreen. We can't call the public drawSprite,
996 since if we're being recorded, we don't want to record this (the 1035 since if we're being recorded, we don't want to record this (the
997 recorder will have already recorded the restore). 1036 recorder will have already recorded the restore).
998 */ 1037 */
999 if (layer) { 1038 if (layer) {
1000 if (layer->fNext) { 1039 if (layer->fNext) {
1001 const SkIPoint& origin = layer->fDevice->getOrigin(); 1040 const SkIPoint& origin = layer->fDevice->getOrigin();
1002 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 1041 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1003 layer->fPaint); 1042 layer->fPaint, layer->fExtraMatrix);
1004 // reset this, since internalDrawDevice will have set it to true 1043 // reset this, since internalDrawDevice will have set it to true
1005 fDeviceCMDirty = true; 1044 fDeviceCMDirty = true;
1006 } 1045 }
1046 if (layer->fPaint && layer->fPaint->fImageFilter) {
1047 fMCRec->fMatrix = layer->fStashedMatrix;
1048 }
1007 SkDELETE(layer); 1049 SkDELETE(layer);
1008 } 1050 }
1009 } 1051 }
1010 1052
1011 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 1053 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
1012 if (NULL == props) { 1054 if (NULL == props) {
1013 props = &fProps; 1055 props = &fProps;
1014 } 1056 }
1015 return this->onNewSurface(info, *props); 1057 return this->onNewSurface(info, *props);
1016 } 1058 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 1143 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
1102 1144
1103 while (iter.next()) { 1145 while (iter.next()) {
1104 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 1146 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
1105 } 1147 }
1106 1148
1107 LOOPER_END 1149 LOOPER_END
1108 } 1150 }
1109 1151
1110 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 1152 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y,
1111 const SkPaint* paint) { 1153 const SkPaint* paint, const SkMatrix& extraMat rix) {
1112 SkPaint tmp; 1154 SkPaint tmp;
1113 if (NULL == paint) { 1155 if (NULL == paint) {
1114 paint = &tmp; 1156 paint = &tmp;
1115 } 1157 }
1116 1158
1117 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1159 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type)
1118 while (iter.next()) { 1160 while (iter.next()) {
1119 SkBaseDevice* dstDev = iter.fDevice; 1161 SkBaseDevice* dstDev = iter.fDevice;
1120 paint = &looper.paint(); 1162 paint = &looper.paint();
1121 SkImageFilter* filter = paint->getImageFilter(); 1163 SkImageFilter* filter = paint->getImageFilter();
1122 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1164 SkIPoint pos = { x - iter.getX(), y - iter.getY() };
1123 if (filter && !dstDev->canHandleImageFilter(filter)) { 1165 if (filter && !dstDev->canHandleImageFilter(filter)) {
1124 SkDeviceImageFilterProxy proxy(dstDev, fProps); 1166 SkDeviceImageFilterProxy proxy(dstDev, fProps);
1125 SkBitmap dst; 1167 SkBitmap dst;
1126 SkIPoint offset = SkIPoint::Make(0, 0); 1168 SkIPoint offset = SkIPoint::Make(0, 0);
1127 const SkBitmap& src = srcDev->accessBitmap(false); 1169 const SkBitmap& src = srcDev->accessBitmap(false);
1128 SkMatrix matrix = *iter.fMatrix; 1170 SkMatrix matrix = *iter.fMatrix;
1129 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y() )); 1171 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y() ));
1130 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height ()); 1172 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height ());
1131 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache ()); 1173 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache ());
1132 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 1174 SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
1133 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 1175 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) {
1134 SkPaint tmpUnfiltered(*paint); 1176 SkPaint tmpUnfiltered(*paint);
1135 tmpUnfiltered.setImageFilter(NULL); 1177 tmpUnfiltered.setImageFilter(NULL);
1136 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of fset.y(), 1178 if (extraMatrix.isIdentity()) {
1137 tmpUnfiltered); 1179 offset += pos;
1180 dstDev->drawSprite(iter, dst, offset.x(), offset.y(),
1181 tmpUnfiltered);
1182 } else {
1183 SkMatrix matrix = extraMatrix;
1184 matrix.preTranslate(offset.x(), offset.y());
1185 dstDev->drawBitmap(iter, dst, matrix,
1186 tmpUnfiltered);
1187 }
1138 } 1188 }
1139 } else { 1189 } else {
1140 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 1190 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
1141 } 1191 }
1142 } 1192 }
1143 LOOPER_END 1193 LOOPER_END
1144 } 1194 }
1145 1195
1146 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { 1196 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) {
1147 if (gTreatSpriteAsBitmap) { 1197 if (gTreatSpriteAsBitmap) {
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 } 2569 }
2520 2570
2521 if (matrix) { 2571 if (matrix) {
2522 canvas->concat(*matrix); 2572 canvas->concat(*matrix);
2523 } 2573 }
2524 } 2574 }
2525 2575
2526 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2576 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2527 fCanvas->restoreToCount(fSaveCount); 2577 fCanvas->restoreToCount(fSaveCount);
2528 } 2578 }
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