blob: fd25bbbca27ae3c051094ccac12c758a944f5f22 [file] [log] [blame]
robertphillips@google.comf4c2c522012-04-27 12:08:47 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrSoftwarePathRenderer.h"
robertphillips976f5f02016-06-03 10:59:20 -07009#include "GrAuditTrail.h"
10#include "GrClip.h"
robertphillips@google.com58b20212012-06-27 20:44:52 +000011#include "GrSWMaskHelper.h"
robertphillips0152d732016-05-20 06:38:43 -070012#include "GrTextureProvider.h"
joshualitt04194f32016-01-13 10:08:27 -080013#include "batches/GrRectBatchFactory.h"
robertphillips@google.comf4c2c522012-04-27 12:08:47 +000014
robertphillips@google.comed4155d2012-05-01 14:30:24 +000015////////////////////////////////////////////////////////////////////////////////
bsalomon0aff2fa2015-07-31 06:48:27 -070016bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
robertphillips0152d732016-05-20 06:38:43 -070017 return SkToBool(fTexProvider);
robertphillips@google.comf4c2c522012-04-27 12:08:47 +000018}
19
robertphillips@google.comed4155d2012-05-01 14:30:24 +000020namespace {
21
22////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comed4155d2012-05-01 14:30:24 +000023// gets device coord bounds of path (not considering the fill) and clip. The
rmistry@google.comd6176b02012-08-23 18:14:13 +000024// path bounds will be a subset of the clip bounds. returns false if
robertphillips@google.comed4155d2012-05-01 14:30:24 +000025// path bounds would be empty.
robertphillips0152d732016-05-20 06:38:43 -070026bool get_path_and_clip_bounds(int width, int height,
cdalton862cff32016-05-12 15:09:48 -070027 const GrClip& clip,
robertphillips@google.comed4155d2012-05-01 14:30:24 +000028 const SkPath& path,
bsalomon@google.comb9086a02012-11-01 18:02:54 +000029 const SkMatrix& matrix,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +000030 SkIRect* devPathBounds,
31 SkIRect* devClipBounds) {
robertphillips@google.comed4155d2012-05-01 14:30:24 +000032 // compute bounds as intersection of rt size, clip, and path
robertphillips0152d732016-05-20 06:38:43 -070033 clip.getConservativeBounds(width, height, devClipBounds);
robertphillips@google.com7b112892012-07-31 15:18:21 +000034
robertphillipse85a32d2015-02-10 08:16:55 -080035 if (devClipBounds->isEmpty()) {
robertphillips0152d732016-05-20 06:38:43 -070036 *devPathBounds = SkIRect::MakeWH(width, height);
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +000037 return false;
robertphillips@google.comed4155d2012-05-01 14:30:24 +000038 }
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +000039
robertphillips@google.com366f1c62012-06-29 21:38:47 +000040 if (!path.getBounds().isEmpty()) {
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +000041 SkRect pathSBounds;
robertphillips@google.com366f1c62012-06-29 21:38:47 +000042 matrix.mapRect(&pathSBounds, path.getBounds());
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +000043 SkIRect pathIBounds;
robertphillips@google.comed4155d2012-05-01 14:30:24 +000044 pathSBounds.roundOut(&pathIBounds);
robertphillipse85a32d2015-02-10 08:16:55 -080045 *devPathBounds = *devClipBounds;
robertphillips@google.com7b112892012-07-31 15:18:21 +000046 if (!devPathBounds->intersect(pathIBounds)) {
bsalomon@google.com276c1fa2012-06-19 13:22:45 +000047 // set the correct path bounds, as this would be used later.
robertphillips@google.com7b112892012-07-31 15:18:21 +000048 *devPathBounds = pathIBounds;
robertphillips@google.comed4155d2012-05-01 14:30:24 +000049 return false;
50 }
51 } else {
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +000052 *devPathBounds = SkIRect::EmptyIRect();
robertphillips@google.comed4155d2012-05-01 14:30:24 +000053 return false;
54 }
55 return true;
56}
57
58////////////////////////////////////////////////////////////////////////////////
robertphillips976f5f02016-06-03 10:59:20 -070059
joshualitt04194f32016-01-13 10:08:27 -080060}
61
robertphillips976f5f02016-06-03 10:59:20 -070062void GrSoftwarePathRenderer::DrawNonAARect(GrDrawContext* drawContext,
63 const GrPaint* paint,
64 const GrUserStencilSettings* userStencilSettings,
65 const GrClip& clip,
66 GrColor color,
67 const SkMatrix& viewMatrix,
68 const SkRect& rect,
69 const SkMatrix& localMatrix) {
70 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
71 nullptr, &localMatrix));
72
csmartdaltonecbc12b2016-06-08 10:08:43 -070073 GrPipelineBuilder pipelineBuilder(*paint, drawContext->mustUseHWAA(*paint));
robertphillips976f5f02016-06-03 10:59:20 -070074 pipelineBuilder.setUserStencil(userStencilSettings);
75
76 drawContext->drawBatch(pipelineBuilder, clip, batch);
77}
78
79void GrSoftwarePathRenderer::DrawAroundInvPath(GrDrawContext* drawContext,
80 const GrPaint* paint,
81 const GrUserStencilSettings* userStencilSettings,
82 const GrClip& clip,
83 GrColor color,
84 const SkMatrix& viewMatrix,
85 const SkIRect& devClipBounds,
86 const SkIRect& devPathBounds) {
joshualittd27f73e2014-12-29 07:43:36 -080087 SkMatrix invert;
joshualitt8059eb92014-12-29 15:10:07 -080088 if (!viewMatrix.invert(&invert)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +000089 return;
90 }
joshualittd27f73e2014-12-29 07:43:36 -080091
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +000092 SkRect rect;
robertphillips@google.com7b112892012-07-31 15:18:21 +000093 if (devClipBounds.fTop < devPathBounds.fTop) {
rmistry@google.comd6176b02012-08-23 18:14:13 +000094 rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
robertphillips@google.com7b112892012-07-31 15:18:21 +000095 devClipBounds.fRight, devPathBounds.fTop);
robertphillips976f5f02016-06-03 10:59:20 -070096 DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
97 SkMatrix::I(), rect, invert);
robertphillips@google.comed4155d2012-05-01 14:30:24 +000098 }
robertphillips@google.com7b112892012-07-31 15:18:21 +000099 if (devClipBounds.fLeft < devPathBounds.fLeft) {
rmistry@google.comd6176b02012-08-23 18:14:13 +0000100 rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
robertphillips@google.com7b112892012-07-31 15:18:21 +0000101 devPathBounds.fLeft, devPathBounds.fBottom);
robertphillips976f5f02016-06-03 10:59:20 -0700102 DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
103 SkMatrix::I(), rect, invert);
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000104 }
robertphillips@google.com7b112892012-07-31 15:18:21 +0000105 if (devClipBounds.fRight > devPathBounds.fRight) {
rmistry@google.comd6176b02012-08-23 18:14:13 +0000106 rect.iset(devPathBounds.fRight, devPathBounds.fTop,
robertphillips@google.com7b112892012-07-31 15:18:21 +0000107 devClipBounds.fRight, devPathBounds.fBottom);
robertphillips976f5f02016-06-03 10:59:20 -0700108 DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
109 SkMatrix::I(), rect, invert);
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000110 }
robertphillips@google.com7b112892012-07-31 15:18:21 +0000111 if (devClipBounds.fBottom > devPathBounds.fBottom) {
rmistry@google.comd6176b02012-08-23 18:14:13 +0000112 rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
robertphillips@google.com7b112892012-07-31 15:18:21 +0000113 devClipBounds.fRight, devClipBounds.fBottom);
robertphillips976f5f02016-06-03 10:59:20 -0700114 DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
115 SkMatrix::I(), rect, invert);
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000116 }
117}
118
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000119////////////////////////////////////////////////////////////////////////////////
120// return true on success; false on failure
bsalomon0aff2fa2015-07-31 06:48:27 -0700121bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
robertphillips976f5f02016-06-03 10:59:20 -0700122 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
123 "GrSoftwarePathRenderer::onDrawPath");
124 if (!fTexProvider) {
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000125 return false;
126 }
127
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000128 SkIRect devPathBounds, devClipBounds;
robertphillips976f5f02016-06-03 10:59:20 -0700129 if (!get_path_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
130 *args.fClip, *args.fPath,
bsalomon0aff2fa2015-07-31 06:48:27 -0700131 *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
132 if (args.fPath->isInverseFillType()) {
robertphillips976f5f02016-06-03 10:59:20 -0700133 DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
134 *args.fClip, args.fColor,
135 *args.fViewMatrix, devClipBounds, devPathBounds);
bsalomon@google.com276c1fa2012-06-19 13:22:45 +0000136 }
137 return true;
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000138 }
robertphillips@google.com366f1c62012-06-29 21:38:47 +0000139
robertphillips@google.com5dfb6722012-07-09 16:32:28 +0000140 SkAutoTUnref<GrTexture> texture(
robertphillips0152d732016-05-20 06:38:43 -0700141 GrSWMaskHelper::DrawPathMaskToTexture(fTexProvider, *args.fPath, *args.fStyle,
sugoi@google.com12b4e272012-12-06 20:13:11 +0000142 devPathBounds,
bsalomon0aff2fa2015-07-31 06:48:27 -0700143 args.fAntiAlias, args.fViewMatrix));
halcanary96fcdcc2015-08-27 07:41:13 -0700144 if (nullptr == texture) {
robertphillips@google.com5dfb6722012-07-09 16:32:28 +0000145 return false;
robertphillips@google.comed4155d2012-05-01 14:30:24 +0000146 }
147
robertphillips976f5f02016-06-03 10:59:20 -0700148 GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fDrawContext, args.fPaint,
149 args.fUserStencilSettings,
cdalton862cff32016-05-12 15:09:48 -0700150 *args.fClip, args.fColor, *args.fViewMatrix,
151 devPathBounds);
robertphillips@google.com5dfb6722012-07-09 16:32:28 +0000152
bsalomon0aff2fa2015-07-31 06:48:27 -0700153 if (args.fPath->isInverseFillType()) {
robertphillips976f5f02016-06-03 10:59:20 -0700154 DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
155 *args.fClip, args.fColor,
156 *args.fViewMatrix, devClipBounds, devPathBounds);
robertphillips@google.com5dfb6722012-07-09 16:32:28 +0000157 }
158
159 return true;
robertphillips@google.comf4c2c522012-04-27 12:08:47 +0000160}