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

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: 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
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(uint32_t 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, uint32_t saveLayerFlags,
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
robertphillips 2015/12/17 19:53:57 We can't just pull some negation trick here ?
reed1 2015/12/17 20:22:31 The bits are in different places, so I'm not sure
1125 uint32_t SkCanvas::SaveFlagsToSaveLayerFlags(SaveFlags flags) {
1126 uint32_t layerFlags = 0;
1127
1128 if (0 == (flags & kMatrix_SaveFlag)) {
1129 layerFlags |= kDontSaveMatrix_PrivateSaveLayerFlag;
1130 }
1131 if (0 == (flags & kClip_SaveFlag)) {
1132 layerFlags |= kDontSaveClip_PrivateSaveLayerFlag;
1133 }
1134 if (0 == (flags & kClipToLayer_SaveFlag)) {
1135 layerFlags |= kDontClipToLayer_PrivateSaveLayerFlag;
1136 }
1137 if (0 == (flags & kHasAlphaLayer_SaveFlag)) {
1138 layerFlags |= kIsOpaque_SaveLayerFlag;
1139 }
1140 return layerFlags;
1141 }
1142
1125 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 1143 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
1126 if (gIgnoreSaveLayerBounds) { 1144 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 } 1145 }
1134 1146
1135 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) { 1147 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl ags) {
1136 if (gIgnoreSaveLayerBounds) { 1148 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 } 1149 }
1144 1150
1145 int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai nt* paint) { 1151 int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai nt* paint) {
1146 unsigned flags = kARGB_ClipLayer_SaveFlag | kPreserveLCDText_PrivateSaveFlag ; 1152 return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLaye rFlag));
1147 return this->saveLayer(bounds, paint, (SaveFlags)flags); 1153 }
1154
1155 int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
1156 SaveLayerRec rec(origRec);
robertphillips 2015/12/17 19:53:57 Do we still need/use gIgnoreSaveLayerBounds ?
reed1 2015/12/17 20:22:31 Dunno. Separate CL I propose.
1157 if (gIgnoreSaveLayerBounds) {
1158 rec.fBounds = nullptr;
1159 }
1160 SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
1161 fSaveCount += 1;
1162 this->internalSaveLayer(rec, strategy);
1163 return this->getSaveCount() - 1;
1148 } 1164 }
1149 1165
1150 static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, Sk BaseDevice* dst) { 1166 static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, Sk BaseDevice* dst) {
1151 1167
1152 SkBitmap srcBM; 1168 SkBitmap srcBM;
1153 1169
1154 #if SK_SUPPORT_GPU 1170 #if SK_SUPPORT_GPU
1155 GrRenderTarget* srcRT = src->accessRenderTarget(); 1171 GrRenderTarget* srcRT = src->accessRenderTarget();
1156 if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { 1172 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, 1173 // 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); 1186 srcBM = src->accessBitmap(false);
1171 } 1187 }
1172 1188
1173 SkCanvas c(dst); 1189 SkCanvas c(dst);
1174 1190
1175 SkPaint p; 1191 SkPaint p;
1176 p.setImageFilter(filter); 1192 p.setImageFilter(filter);
1177 c.drawBitmap(srcBM, 0, 0, &p); 1193 c.drawBitmap(srcBM, 0, 0, &p);
1178 } 1194 }
1179 1195
1180 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav eFlags flags, 1196 void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra tegy) {
1181 SaveLayerStrategy strategy) { 1197 const SkRect* bounds = rec.fBounds;
1198 const SkPaint* paint = rec.fPaint;
1199 uint32_t saveLayerFlags = rec.fSaveLayerFlags;
1200
1182 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 1201 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
1183 flags |= kClipToLayer_SaveFlag; 1202 saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag;
1184 #endif 1203 #endif
1185 1204
1186 // do this before we create the layer. We don't call the public save() since 1205 // do this before we create the layer. We don't call the public save() since
1187 // that would invoke a possibly overridden virtual 1206 // that would invoke a possibly overridden virtual
1188 this->internalSave(); 1207 this->internalSave();
1189 1208
1190 fDeviceCMDirty = true; 1209 fDeviceCMDirty = true;
1191 1210
1192 SkIRect ir; 1211 SkIRect ir;
1193 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : nullptr)) { 1212 if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, paint ? paint->getIma geFilter() : nullptr)) {
1194 return; 1213 return;
1195 } 1214 }
1196 1215
1197 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1216 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
1198 // the clipRectBounds() call above? 1217 // the clipRectBounds() call above?
1199 if (kNoLayer_SaveLayerStrategy == strategy) { 1218 if (kNoLayer_SaveLayerStrategy == strategy) {
1200 return; 1219 return;
1201 } 1220 }
1202 1221
1203 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 1222 bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag);
1204 SkPixelGeometry geo = fProps.pixelGeometry(); 1223 SkPixelGeometry geo = fProps.pixelGeometry();
1205 if (paint) { 1224 if (paint) {
1206 // TODO: perhaps add a query to filters so we might preserve opaqueness. .. 1225 // TODO: perhaps add a query to filters so we might preserve opaqueness. ..
1207 if (paint->getImageFilter() || paint->getColorFilter()) { 1226 if (paint->getImageFilter() || paint->getColorFilter()) {
1208 isOpaque = false; 1227 isOpaque = false;
1209 geo = kUnknown_SkPixelGeometry; 1228 geo = kUnknown_SkPixelGeometry;
1210 } 1229 }
1211 } 1230 }
1212 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 1231 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(),
1213 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 1232 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
1214 1233
1215 SkBaseDevice* device = this->getTopDevice(); 1234 SkBaseDevice* device = this->getTopDevice();
1216 if (nullptr == device) { 1235 if (nullptr == device) {
1217 SkDebugf("Unable to find device for layer."); 1236 SkDebugf("Unable to find device for layer.");
1218 return; 1237 return;
1219 } 1238 }
1220 1239
1221 bool forceSpriteOnRestore = false; 1240 bool forceSpriteOnRestore = false;
1222 { 1241 {
1223 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 1242 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
1224 SkToBool(flags & kPreserveLCDText_PrivateSa veFlag); 1243 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag);
1225 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 1244 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
1226 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo, 1245 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo,
1227 pres erveLCDText, false); 1246 pres erveLCDText, false);
1228 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 1247 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint);
1229 if (nullptr == newDev) { 1248 if (nullptr == newDev) {
1230 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h andle the paint) 1249 // 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); 1250 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG eometry);
1232 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 1251 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps);
1233 if (nullptr == newDev) { 1252 if (nullptr == newDev) {
1234 SkErrorInternals::SetError(kInternalError_SkError, 1253 SkErrorInternals::SetError(kInternalError_SkError,
(...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 } 3033 }
3015 3034
3016 if (matrix) { 3035 if (matrix) {
3017 canvas->concat(*matrix); 3036 canvas->concat(*matrix);
3018 } 3037 }
3019 } 3038 }
3020 3039
3021 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3040 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3022 fCanvas->restoreToCount(fSaveCount); 3041 fCanvas->restoreToCount(fSaveCount);
3023 } 3042 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698