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

Side by Side Diff: src/gpu/GrDrawContext.cpp

Issue 1157773003: Move SkGpuDevice::internalDrawPath to GrBlurUtils::drawPathWithMaskFilter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clean up Created 5 years, 7 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
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrAARectRenderer.h" 9 #include "GrAARectRenderer.h"
10 #include "GrBatch.h" 10 #include "GrBatch.h"
11 #include "GrBatchTest.h" 11 #include "GrBatchTest.h"
12 #include "GrDefaultGeoProcFactory.h" 12 #include "GrDefaultGeoProcFactory.h"
13 #include "GrDrawContext.h" 13 #include "GrDrawContext.h"
14 #include "GrOvalRenderer.h" 14 #include "GrOvalRenderer.h"
15 #include "GrPathRenderer.h" 15 #include "GrPathRenderer.h"
16 #include "SkGr.h"
17 #include "SkMaskFilter.h"
18 #include "SkPaint.h"
16 19
17 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) 20 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext)
18 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } 21 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; }
19 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } 22 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; }
20 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; } 23 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; }
21 24
22 class AutoCheckFlush { 25 class AutoCheckFlush {
23 public: 26 public:
24 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); } 27 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
25 ~AutoCheckFlush() { fContext->flushIfNecessary(); } 28 ~AutoCheckFlush() { fContext->flushIfNecessary(); }
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 ovalRect, 1038 ovalRect,
1036 strokeInfo)) { 1039 strokeInfo)) {
1037 return; 1040 return;
1038 } 1041 }
1039 } 1042 }
1040 } 1043 }
1041 this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, pai nt.isAntiAlias(), 1044 this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, pai nt.isAntiAlias(),
1042 path, strokeInfo); 1045 path, strokeInfo);
1043 } 1046 }
1044 1047
1048 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r ect) {
1049 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo unds, rect);
1050 }
1051
1052 // Draw a mask using the supplied paint. Since the coverage/geometry
1053 // is already burnt into the mask this boils down to a rect draw.
1054 // Return true if the mask was successfully drawn.
1055 static bool draw_mask(GrDrawContext* drawContext,
1056 GrRenderTarget* rt,
1057 const GrClip& clip,
1058 const SkMatrix& viewMatrix,
1059 const SkRect& maskRect,
1060 GrPaint* grp,
1061 GrTexture* mask) {
1062 SkMatrix matrix;
1063 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
1064 matrix.postIDiv(mask->width(), mask->height());
1065
1066 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix,
1067 kDevice_GrCoordSet)) ->unref();
1068
1069 SkMatrix inverse;
1070 if (!viewMatrix.invert(&inverse)) {
1071 return false;
1072 }
1073 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), mas kRect, inverse);
1074 return true;
1075 }
1076
1077 static bool draw_with_mask_filter(GrDrawContext* drawContext,
1078 GrTextureProvider* textureProvider,
1079 GrRenderTarget* rt,
1080 const GrClip& clipData,
1081 const SkMatrix& viewMatrix,
1082 const SkPath& devPath,
1083 SkMaskFilter* filter,
1084 const SkIRect& clipBounds,
1085 GrPaint* grp,
1086 SkPaint::Style style) {
1087 SkMask srcM, dstM;
1088
1089 if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
1090 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) {
1091 return false;
1092 }
1093 SkAutoMaskFreeImage autoSrc(srcM.fImage);
1094
1095 if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) {
1096 return false;
1097 }
1098 // this will free-up dstM when we're done (allocated in filterMask())
1099 SkAutoMaskFreeImage autoDst(dstM.fImage);
1100
1101 if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) {
1102 return false;
1103 }
1104
1105 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
1106 // the current clip (and identity matrix) and GrPaint settings
1107 GrSurfaceDesc desc;
1108 desc.fWidth = dstM.fBounds.width();
1109 desc.fHeight = dstM.fBounds.height();
1110 desc.fConfig = kAlpha_8_GrPixelConfig;
1111
1112 SkAutoTUnref<GrTexture> texture(textureProvider->refScratchTexture(
1113 desc, GrTextureProvider::kApprox_ScratchTexMatch));
1114 if (!texture) {
1115 return false;
1116 }
1117 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
1118 dstM.fImage, dstM.fRowBytes);
1119
1120 SkRect maskRect = SkRect::Make(dstM.fBounds);
1121
1122 return draw_mask(drawContext, rt, clipData, viewMatrix, maskRect, grp, textu re);
1123 }
1124
1125 // Create a mask of 'devPath' and place the result in 'mask'.
1126 static GrTexture* create_mask_GPU(GrContext* context,
1127 const SkRect& maskRect,
1128 const SkPath& devPath,
1129 const GrStrokeInfo& strokeInfo,
1130 bool doAA,
1131 int sampleCnt) {
1132 GrSurfaceDesc desc;
1133 desc.fFlags = kRenderTarget_GrSurfaceFlag;
1134 desc.fWidth = SkScalarCeilToInt(maskRect.width());
1135 desc.fHeight = SkScalarCeilToInt(maskRect.height());
1136 desc.fSampleCnt = doAA ? sampleCnt : 0;
1137 // We actually only need A8, but it often isn't supported as a
1138 // render target so default to RGBA_8888
1139 desc.fConfig = kRGBA_8888_GrPixelConfig;
1140
1141 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig,
1142 desc.fSampleCnt > 0)) {
1143 desc.fConfig = kAlpha_8_GrPixelConfig;
1144 }
1145
1146 GrTexture* mask = context->textureProvider()->refScratchTexture(
1147 desc, GrTextureProvider::kApprox_ScratchTexMatch);
1148 if (NULL == mask) {
1149 return NULL;
1150 }
1151
1152 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
1153
1154 GrDrawContext* drawContext = context->drawContext();
1155 if (!drawContext) {
1156 return NULL;
1157 }
1158
1159 drawContext->clear(mask->asRenderTarget(), NULL, 0x0, true);
1160
1161 GrPaint tempPaint;
1162 tempPaint.setAntiAlias(doAA);
1163 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
1164
1165 // setup new clip
1166 GrClip clip(clipRect);
1167
1168 // Draw the mask into maskTexture with the path's top-left at the origin usi ng tempPaint.
1169 SkMatrix translate;
1170 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
1171 drawContext->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, de vPath, strokeInfo);
1172 return mask;
1173 }
1174
1175 void GrDrawContext::drawPathFull(GrContext* context,
1176 GrRenderTarget* renderTarget,
1177 const GrClip& clip,
1178 const SkPath& origSrcPath,
1179 const SkPaint& paint,
1180 const SkMatrix& origViewMatrix,
1181 const SkMatrix* prePathMatrix,
1182 const SkIRect& clipBounds,
1183 bool pathIsMutable) {
1184 SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
1185
1186 GrStrokeInfo strokeInfo(paint);
1187
1188 // If we have a prematrix, apply it to the path, optimizing for the case
1189 // where the original path can in fact be modified in place (even though
1190 // its parameter type is const).
1191 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
1192 SkTLazy<SkPath> tmpPath;
1193 SkTLazy<SkPath> effectPath;
1194 SkPathEffect* pathEffect = paint.getPathEffect();
1195
1196 SkMatrix viewMatrix = origViewMatrix;
1197
1198 if (prePathMatrix) {
1199 // stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
1200 // The pre-path-matrix also should not affect shading.
1201 if (NULL == paint.getMaskFilter() && NULL == pathEffect && NULL == paint .getShader() &&
1202 (strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
1203 viewMatrix.preConcat(*prePathMatrix);
1204 } else {
1205 SkPath* result = pathPtr;
1206
1207 if (!pathIsMutable) {
1208 result = tmpPath.init();
1209 result->setIsVolatile(true);
1210 pathIsMutable = true;
1211 }
1212 // should I push prePathMatrix on our MV stack temporarily, instead
1213 // of applying it here? See SkDraw.cpp
1214 pathPtr->transform(*prePathMatrix, result);
1215 pathPtr = result;
1216 }
1217 }
1218 // at this point we're done with prePathMatrix
1219 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
1220
1221 GrPaint grPaint;
1222 if (!SkPaint2GrPaint(context, renderTarget, paint, viewMatrix, true, &grPain t)) {
1223 return;
1224 }
1225
1226 const SkRect* cullRect = NULL; // TODO: what is our bounds?
1227 if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(effectPat h.init(), *pathPtr,
1228 &strokeIn fo, cullRect)) {
1229 pathPtr = effectPath.get();
1230 pathIsMutable = true;
1231 }
1232
1233 if (paint.getMaskFilter()) {
1234 if (!strokeInfo.isHairlineStyle()) {
1235 SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
1236 if (strokeInfo.isDashed()) {
1237 if (pathEffect->filterPath(strokedPath, *pathPtr, &strokeInfo, c ullRect)) {
1238 pathPtr = strokedPath;
1239 pathIsMutable = true;
1240 }
1241 strokeInfo.removeDash();
1242 }
1243 if (strokeInfo.applyToPath(strokedPath, *pathPtr)) {
1244 pathPtr = strokedPath;
1245 pathIsMutable = true;
1246 strokeInfo.setFillStyle();
1247 }
1248 }
1249
1250 // avoid possibly allocating a new path in transform if we can
1251 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
1252 if (!pathIsMutable) {
1253 devPathPtr->setIsVolatile(true);
1254 }
1255
1256 // transform the path into device space
1257 pathPtr->transform(viewMatrix, devPathPtr);
1258
1259 SkRect maskRect;
1260 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
1261 clipBounds,
1262 viewMatrix,
1263 &maskRect)) {
1264 SkIRect finalIRect;
1265 maskRect.roundOut(&finalIRect);
1266 if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
1267 // clipped out
1268 return;
1269 }
1270
1271 if (paint.getMaskFilter()->directFilterMaskGPU(context,
1272 renderTarget,
1273 &grPaint,
1274 clip,
1275 viewMatrix,
1276 strokeInfo,
1277 *devPathPtr)) {
1278 // the mask filter was able to draw itself directly, so there's nothing
1279 // left to do.
1280 return;
1281 }
1282
1283
1284 SkAutoTUnref<GrTexture> mask(create_mask_GPU(context,
1285 maskRect,
1286 *devPathPtr,
1287 strokeInfo,
1288 grPaint.isAntiAlias(),
1289 renderTarget->numSample s()));
1290 if (mask) {
1291 GrTexture* filtered;
1292
1293 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR ect,
1294 &filtered, true)) {
1295 // filterMaskGPU gives us ownership of a ref to the result
1296 SkAutoTUnref<GrTexture> atu(filtered);
1297 if (draw_mask(this,
1298 renderTarget,
1299 clip,
1300 viewMatrix,
1301 maskRect,
1302 &grPaint,
1303 filtered)) {
1304 // This path is completely drawn
1305 return;
1306 }
1307 }
1308 }
1309 }
1310
1311 // draw the mask on the CPU - this is a fallthrough path in case the
1312 // GPU path fails
1313 SkPaint::Style style = strokeInfo.isHairlineStyle() ? SkPaint::kStroke_S tyle :
1314 SkPaint::kFill_Sty le;
1315 draw_with_mask_filter(this, context->textureProvider(), renderTarget,
1316 clip, viewMatrix, *devPathPtr,
1317 paint.getMaskFilter(), clipBounds, &grPaint, style );
1318 return;
1319 }
1320
1321 this->drawPath(renderTarget, clip, grPaint, viewMatrix, *pathPtr, strokeInfo );
1322 }
1323
1324
1045 void GrDrawContext::internalDrawPath(GrDrawTarget* target, 1325 void GrDrawContext::internalDrawPath(GrDrawTarget* target,
1046 GrPipelineBuilder* pipelineBuilder, 1326 GrPipelineBuilder* pipelineBuilder,
1047 const SkMatrix& viewMatrix, 1327 const SkMatrix& viewMatrix,
1048 GrColor color, 1328 GrColor color,
1049 bool useAA, 1329 bool useAA,
1050 const SkPath& path, 1330 const SkPath& path,
1051 const GrStrokeInfo& strokeInfo) { 1331 const GrStrokeInfo& strokeInfo) {
1052 RETURN_IF_ABANDONED 1332 RETURN_IF_ABANDONED
1053 SkASSERT(!path.isEmpty()); 1333 SkASSERT(!path.isEmpty());
1054 1334
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 return DrawVerticesBatch::Create(geometry, type, viewMatrix, 1542 return DrawVerticesBatch::Create(geometry, type, viewMatrix,
1263 positions.begin(), vertexCount, 1543 positions.begin(), vertexCount,
1264 indices.begin(), hasIndices ? vertexCount : 0, 1544 indices.begin(), hasIndices ? vertexCount : 0,
1265 colors.begin(), 1545 colors.begin(),
1266 texCoords.begin(), 1546 texCoords.begin(),
1267 bounds); 1547 bounds);
1268 } 1548 }
1269 1549
1270 #endif 1550 #endif
1271 1551
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698