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

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

Issue 1533953002: change signature for virtual related to saveLayer, passing SaveLayerRec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update comment Created 5 years 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/utils/SkNoSaveLayerCanvas.h ('k') | src/core/SkPictureFlat.h » ('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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 * draw onto the previous layer using the xfermode from the ori ginal paint. 474 * draw onto the previous layer using the xfermode from the ori ginal paint.
475 */ 475 */
476 SkPaint tmp; 476 SkPaint tmp;
477 tmp.setImageFilter(fPaint->getImageFilter()); 477 tmp.setImageFilter(fPaint->getImageFilter());
478 tmp.setXfermode(fPaint->getXfermode()); 478 tmp.setXfermode(fPaint->getXfermode());
479 SkRect storage; 479 SkRect storage;
480 if (rawBounds) { 480 if (rawBounds) {
481 // Make rawBounds include all paint outsets except for those due to image filters. 481 // Make rawBounds include all paint outsets except for those due to image filters.
482 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra wBounds, &storage); 482 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra wBounds, &storage);
483 } 483 }
484 (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_Cli pLayer_SaveFlag, 484 (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &t mp, 0),
485 SkCanvas::kFullLayer_SaveLayerStrate gy); 485 SkCanvas::kFullLayer_SaveLayerStrate gy);
486 fTempLayerForImageFilter = true; 486 fTempLayerForImageFilter = true;
487 // we remove the imagefilter/xfermode inside doNext() 487 // we remove the imagefilter/xfermode inside doNext()
488 } 488 }
489 489
490 if (SkDrawLooper* looper = paint.getLooper()) { 490 if (SkDrawLooper* looper = paint.getLooper()) {
491 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( 491 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>(
492 looper->contextSize()); 492 looper->contextSize());
493 fLooperContext = looper->createContext(canvas, buffer); 493 fLooperContext = looper->createContext(canvas, buffer);
494 fIsSimple = false; 494 fIsSimple = false;
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 } 1046 }
1047 1047
1048 void SkCanvas::internalSave() { 1048 void SkCanvas::internalSave() {
1049 MCRec* newTop = (MCRec*)fMCStack.push_back(); 1049 MCRec* newTop = (MCRec*)fMCStack.push_back();
1050 new (newTop) MCRec(*fMCRec); // balanced in restore() 1050 new (newTop) MCRec(*fMCRec); // balanced in restore()
1051 fMCRec = newTop; 1051 fMCRec = newTop;
1052 1052
1053 fClipStack->save(); 1053 fClipStack->save();
1054 } 1054 }
1055 1055
1056 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 1056 bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
1057 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 1057 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
1058 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 1058 return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag);
1059 #else 1059 #else
1060 return true; 1060 return true;
1061 #endif 1061 #endif
1062 } 1062 }
1063 1063
1064 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 1064 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag s,
1065 SkIRect* intersection, const SkImageFilter* imageF ilter) { 1065 SkIRect* intersection, const SkImageFilter* imageF ilter) {
1066 SkIRect clipBounds; 1066 SkIRect clipBounds;
1067 if (!this->getClipDeviceBounds(&clipBounds)) { 1067 if (!this->getClipDeviceBounds(&clipBounds)) {
1068 return false; 1068 return false;
1069 } 1069 }
1070 1070
1071 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 1071 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix()
1072 1072
1073 // This is a temporary hack, until individual filters can do their own 1073 // This is a temporary hack, until individual filters can do their own
1074 // bloating, when this will be removed. 1074 // bloating, when this will be removed.
(...skipping 16 matching lines...) Expand all
1091 #endif 1091 #endif
1092 } 1092 }
1093 SkIRect ir; 1093 SkIRect ir;
1094 if (bounds) { 1094 if (bounds) {
1095 SkRect r; 1095 SkRect r;
1096 1096
1097 ctm.mapRect(&r, *bounds); 1097 ctm.mapRect(&r, *bounds);
1098 r.roundOut(&ir); 1098 r.roundOut(&ir);
1099 // early exit if the layer's bounds are clipped out 1099 // early exit if the layer's bounds are clipped out
1100 if (!ir.intersect(clipBounds)) { 1100 if (!ir.intersect(clipBounds)) {
1101 if (bounds_affects_clip(flags)) { 1101 if (BoundsAffectsClip(saveLayerFlags)) {
1102 fCachedLocalClipBoundsDirty = true; 1102 fCachedLocalClipBoundsDirty = true;
1103 fMCRec->fRasterClip.setEmpty(); 1103 fMCRec->fRasterClip.setEmpty();
1104 } 1104 }
1105 return false; 1105 return false;
1106 } 1106 }
1107 } else { // no user bounds, so just use the clip 1107 } else { // no user bounds, so just use the clip
1108 ir = clipBounds; 1108 ir = clipBounds;
1109 } 1109 }
1110 SkASSERT(!ir.isEmpty()); 1110 SkASSERT(!ir.isEmpty());
1111 1111
1112 if (bounds_affects_clip(flags)) { 1112 if (BoundsAffectsClip(saveLayerFlags)) {
1113 // Simplify the current clips since they will be applied properly during restore() 1113 // Simplify the current clips since they will be applied properly during restore()
1114 fCachedLocalClipBoundsDirty = true; 1114 fCachedLocalClipBoundsDirty = true;
1115 fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1115 fClipStack->clipDevRect(ir, SkRegion::kReplace_Op);
1116 fMCRec->fRasterClip.setRect(ir); 1116 fMCRec->fRasterClip.setRect(ir);
1117 } 1117 }
1118 1118
1119 if (intersection) { 1119 if (intersection) {
1120 *intersection = ir; 1120 *intersection = ir;
1121 } 1121 }
1122 return true; 1122 return true;
1123 } 1123 }
1124 1124
1125 uint32_t SkCanvas::SaveFlagsToSaveLayerFlags(SaveFlags flags) {
1126 uint32_t layerFlags = 0;
1127
1128 if (0 == (flags & kClipToLayer_SaveFlag)) {
1129 layerFlags |= kDontClipToLayer_PrivateSaveLayerFlag;
1130 }
1131 if (0 == (flags & kHasAlphaLayer_SaveFlag)) {
1132 layerFlags |= kIsOpaque_SaveLayerFlag;
1133 }
1134 return layerFlags;
1135 }
1136
1137 #ifdef SK_SUPPORT_LEGACY_SAVELAYERPARAMS
1138 SkCanvas::SaveLayerStrategy SkCanvas::getSaveLayerStrategy(const SaveLayerRec& r ec) {
1139 uint32_t flags = 0;
1140
1141 if (0 == (rec.fSaveLayerFlags & kDontClipToLayer_PrivateSaveLayerFlag)) {
1142 flags |= kClipToLayer_SaveFlag;
1143 }
1144 if (0 == (rec.fSaveLayerFlags & kIsOpaque_SaveLayerFlag)) {
1145 flags |= kHasAlphaLayer_SaveFlag;
1146 }
1147 return this->willSaveLayer(rec.fBounds, rec.fPaint, (SaveFlags)flags);
1148 }
1149 #endif
1150
1125 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 1151 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
1126 if (gIgnoreSaveLayerBounds) { 1152 return this->saveLayer(SaveLayerRec(bounds, paint, 0));
1127 bounds = nullptr;
1128 }
1129 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLa yer_SaveFlag);
1130 fSaveCount += 1;
1131 this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy);
1132 return this->getSaveCount() - 1;
1133 } 1153 }
1134 1154
1135 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) { 1155 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) {
1136 if (gIgnoreSaveLayerBounds) { 1156 return this->saveLayer(SaveLayerRec(bounds, paint, SaveFlagsToSaveLayerFlags (flags)));
1137 bounds = nullptr;
1138 }
1139 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags);
1140 fSaveCount += 1;
1141 this->internalSaveLayer(bounds, paint, flags, strategy);
1142 return this->getSaveCount() - 1;
1143 } 1157 }
1144 1158
1145 int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai nt* paint) { 1159 int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai nt* paint) {
1146 unsigned flags = kARGB_ClipLayer_SaveFlag | kPreserveLCDText_PrivateSaveFlag ; 1160 return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLaye rFlag));
1147 return this->saveLayer(bounds, paint, (SaveFlags)flags); 1161 }
1162
1163 int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
1164 SaveLayerRec rec(origRec);
1165 if (gIgnoreSaveLayerBounds) {
1166 rec.fBounds = nullptr;
1167 }
1168 SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
1169 fSaveCount += 1;
1170 this->internalSaveLayer(rec, strategy);
1171 return this->getSaveCount() - 1;
1148 } 1172 }
1149 1173
1150 static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, Sk BaseDevice* dst) { 1174 static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, Sk BaseDevice* dst) {
1151 1175
1152 SkBitmap srcBM; 1176 SkBitmap srcBM;
1153 1177
1154 #if SK_SUPPORT_GPU 1178 #if SK_SUPPORT_GPU
1155 GrRenderTarget* srcRT = src->accessRenderTarget(); 1179 GrRenderTarget* srcRT = src->accessRenderTarget();
1156 if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { 1180 if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) {
1157 // When both the src & the dst are on the gpu but the src doesn't have a texture, 1181 // When both the src & the dst are on the gpu but the src doesn't have a texture,
(...skipping 12 matching lines...) Expand all
1170 srcBM = src->accessBitmap(false); 1194 srcBM = src->accessBitmap(false);
1171 } 1195 }
1172 1196
1173 SkCanvas c(dst); 1197 SkCanvas c(dst);
1174 1198
1175 SkPaint p; 1199 SkPaint p;
1176 p.setImageFilter(filter); 1200 p.setImageFilter(filter);
1177 c.drawBitmap(srcBM, 0, 0, &p); 1201 c.drawBitmap(srcBM, 0, 0, &p);
1178 } 1202 }
1179 1203
1180 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 1204 void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra tegy) {
1181 SaveLayerStrategy strategy) { 1205 const SkRect* bounds = rec.fBounds;
1206 const SkPaint* paint = rec.fPaint;
1207 SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags;
1208
1182 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 1209 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
1183 flags |= kClipToLayer_SaveFlag; 1210 saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag;
1184 #endif 1211 #endif
1185 1212
1186 // do this before we create the layer. We don't call the public save() since 1213 // do this before we create the layer. We don't call the public save() since
1187 // that would invoke a possibly overridden virtual 1214 // that would invoke a possibly overridden virtual
1188 this->internalSave(); 1215 this->internalSave();
1189 1216
1190 fDeviceCMDirty = true; 1217 fDeviceCMDirty = true;
1191 1218
1192 SkIRect ir; 1219 SkIRect ir;
1193 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : nullptr)) { 1220 if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, paint ? paint->getIma geFilter() : nullptr)) {
1194 return; 1221 return;
1195 } 1222 }
1196 1223
1197 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1224 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
1198 // the clipRectBounds() call above? 1225 // the clipRectBounds() call above?
1199 if (kNoLayer_SaveLayerStrategy == strategy) { 1226 if (kNoLayer_SaveLayerStrategy == strategy) {
1200 return; 1227 return;
1201 } 1228 }
1202 1229
1203 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 1230 bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag);
1204 SkPixelGeometry geo = fProps.pixelGeometry(); 1231 SkPixelGeometry geo = fProps.pixelGeometry();
1205 if (paint) { 1232 if (paint) {
1206 // TODO: perhaps add a query to filters so we might preserve opaqueness. .. 1233 // TODO: perhaps add a query to filters so we might preserve opaqueness. ..
1207 if (paint->getImageFilter() || paint->getColorFilter()) { 1234 if (paint->getImageFilter() || paint->getColorFilter()) {
1208 isOpaque = false; 1235 isOpaque = false;
1209 geo = kUnknown_SkPixelGeometry; 1236 geo = kUnknown_SkPixelGeometry;
1210 } 1237 }
1211 } 1238 }
1212 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 1239 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(),
1213 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 1240 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
1214 1241
1215 SkBaseDevice* device = this->getTopDevice(); 1242 SkBaseDevice* device = this->getTopDevice();
1216 if (nullptr == device) { 1243 if (nullptr == device) {
1217 SkDebugf("Unable to find device for layer."); 1244 SkDebugf("Unable to find device for layer.");
1218 return; 1245 return;
1219 } 1246 }
1220 1247
1221 bool forceSpriteOnRestore = false; 1248 bool forceSpriteOnRestore = false;
1222 { 1249 {
1223 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 1250 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
1224 SkToBool(flags & kPreserveLCDText_PrivateSa veFlag); 1251 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag);
1225 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 1252 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
1226 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo, 1253 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo,
1227 pres erveLCDText, false); 1254 pres erveLCDText, false);
1228 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 1255 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint);
1229 if (nullptr == newDev) { 1256 if (nullptr == newDev) {
1230 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h andle the paint) 1257 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h andle the paint)
1231 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG eometry); 1258 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG eometry);
1232 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 1259 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps);
1233 if (nullptr == newDev) { 1260 if (nullptr == newDev) {
1234 SkErrorInternals::SetError(kInternalError_SkError, 1261 SkErrorInternals::SetError(kInternalError_SkError,
(...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 } 3041 }
3015 3042
3016 if (matrix) { 3043 if (matrix) {
3017 canvas->concat(*matrix); 3044 canvas->concat(*matrix);
3018 } 3045 }
3019 } 3046 }
3020 3047
3021 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3048 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3022 fCanvas->restoreToCount(fSaveCount); 3049 fCanvas->restoreToCount(fSaveCount);
3023 } 3050 }
OLDNEW
« no previous file with comments | « include/utils/SkNoSaveLayerCanvas.h ('k') | src/core/SkPictureFlat.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698