OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
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 "GrSoftwarePathRenderer.h" | 8 #include "GrSoftwarePathRenderer.h" |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "GrSWMaskHelper.h" | 10 #include "GrSWMaskHelper.h" |
11 #include "batches/GrRectBatchFactory.h" | 11 #include "batches/GrRectBatchFactory.h" |
12 | 12 |
13 //////////////////////////////////////////////////////////////////////////////// | 13 //////////////////////////////////////////////////////////////////////////////// |
14 bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { | 14 bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
15 return SkToBool(fContext); | 15 return SkToBool(fContext); |
16 } | 16 } |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 //////////////////////////////////////////////////////////////////////////////// | 20 //////////////////////////////////////////////////////////////////////////////// |
21 // gets device coord bounds of path (not considering the fill) and clip. The | 21 // gets device coord bounds of path (not considering the fill) and clip. The |
22 // path bounds will be a subset of the clip bounds. returns false if | 22 // path bounds will be a subset of the clip bounds. returns false if |
23 // path bounds would be empty. | 23 // path bounds would be empty. |
24 bool get_path_and_clip_bounds(const GrPipelineBuilder* pipelineBuilder, | 24 bool get_path_and_clip_bounds(const GrPipelineBuilder* pipelineBuilder, |
| 25 const GrClip& clip, |
25 const SkPath& path, | 26 const SkPath& path, |
26 const SkMatrix& matrix, | 27 const SkMatrix& matrix, |
27 SkIRect* devPathBounds, | 28 SkIRect* devPathBounds, |
28 SkIRect* devClipBounds) { | 29 SkIRect* devClipBounds) { |
29 // compute bounds as intersection of rt size, clip, and path | 30 // compute bounds as intersection of rt size, clip, and path |
30 const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 31 const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); |
31 if (nullptr == rt) { | 32 if (nullptr == rt) { |
32 return false; | 33 return false; |
33 } | 34 } |
34 | 35 |
35 pipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), dev
ClipBounds); | 36 clip.getConservativeBounds(rt->width(), rt->height(), devClipBounds); |
36 | 37 |
37 if (devClipBounds->isEmpty()) { | 38 if (devClipBounds->isEmpty()) { |
38 *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 39 *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); |
39 return false; | 40 return false; |
40 } | 41 } |
41 | 42 |
42 if (!path.getBounds().isEmpty()) { | 43 if (!path.getBounds().isEmpty()) { |
43 SkRect pathSBounds; | 44 SkRect pathSBounds; |
44 matrix.mapRect(&pathSBounds, path.getBounds()); | 45 matrix.mapRect(&pathSBounds, path.getBounds()); |
45 SkIRect pathIBounds; | 46 SkIRect pathIBounds; |
46 pathSBounds.roundOut(&pathIBounds); | 47 pathSBounds.roundOut(&pathIBounds); |
47 *devPathBounds = *devClipBounds; | 48 *devPathBounds = *devClipBounds; |
48 if (!devPathBounds->intersect(pathIBounds)) { | 49 if (!devPathBounds->intersect(pathIBounds)) { |
49 // set the correct path bounds, as this would be used later. | 50 // set the correct path bounds, as this would be used later. |
50 *devPathBounds = pathIBounds; | 51 *devPathBounds = pathIBounds; |
51 return false; | 52 return false; |
52 } | 53 } |
53 } else { | 54 } else { |
54 *devPathBounds = SkIRect::EmptyIRect(); | 55 *devPathBounds = SkIRect::EmptyIRect(); |
55 return false; | 56 return false; |
56 } | 57 } |
57 return true; | 58 return true; |
58 } | 59 } |
59 | 60 |
60 //////////////////////////////////////////////////////////////////////////////// | 61 //////////////////////////////////////////////////////////////////////////////// |
61 static void draw_non_aa_rect(GrDrawTarget* drawTarget, | 62 static void draw_non_aa_rect(GrDrawTarget* drawTarget, |
62 const GrPipelineBuilder& pipelineBuilder, | 63 const GrPipelineBuilder& pipelineBuilder, |
| 64 const GrClip& clip, |
63 GrColor color, | 65 GrColor color, |
64 const SkMatrix& viewMatrix, | 66 const SkMatrix& viewMatrix, |
65 const SkRect& rect, | 67 const SkRect& rect, |
66 const SkMatrix& localMatrix) { | 68 const SkMatrix& localMatrix) { |
67 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, | 69 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, |
68 nullptr,
&localMatrix)); | 70 nullptr,
&localMatrix)); |
69 drawTarget->drawBatch(pipelineBuilder, batch); | 71 drawTarget->drawBatch(pipelineBuilder, clip, batch); |
70 } | 72 } |
71 | 73 |
72 void draw_around_inv_path(GrDrawTarget* target, | 74 void draw_around_inv_path(GrDrawTarget* target, |
73 GrPipelineBuilder* pipelineBuilder, | 75 GrPipelineBuilder* pipelineBuilder, |
| 76 const GrClip& clip, |
74 GrColor color, | 77 GrColor color, |
75 const SkMatrix& viewMatrix, | 78 const SkMatrix& viewMatrix, |
76 const SkIRect& devClipBounds, | 79 const SkIRect& devClipBounds, |
77 const SkIRect& devPathBounds) { | 80 const SkIRect& devPathBounds) { |
78 SkMatrix invert; | 81 SkMatrix invert; |
79 if (!viewMatrix.invert(&invert)) { | 82 if (!viewMatrix.invert(&invert)) { |
80 return; | 83 return; |
81 } | 84 } |
82 | 85 |
83 SkRect rect; | 86 SkRect rect; |
84 if (devClipBounds.fTop < devPathBounds.fTop) { | 87 if (devClipBounds.fTop < devPathBounds.fTop) { |
85 rect.iset(devClipBounds.fLeft, devClipBounds.fTop, | 88 rect.iset(devClipBounds.fLeft, devClipBounds.fTop, |
86 devClipBounds.fRight, devPathBounds.fTop); | 89 devClipBounds.fRight, devPathBounds.fTop); |
87 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 90 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
88 } | 91 } |
89 if (devClipBounds.fLeft < devPathBounds.fLeft) { | 92 if (devClipBounds.fLeft < devPathBounds.fLeft) { |
90 rect.iset(devClipBounds.fLeft, devPathBounds.fTop, | 93 rect.iset(devClipBounds.fLeft, devPathBounds.fTop, |
91 devPathBounds.fLeft, devPathBounds.fBottom); | 94 devPathBounds.fLeft, devPathBounds.fBottom); |
92 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 95 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
93 } | 96 } |
94 if (devClipBounds.fRight > devPathBounds.fRight) { | 97 if (devClipBounds.fRight > devPathBounds.fRight) { |
95 rect.iset(devPathBounds.fRight, devPathBounds.fTop, | 98 rect.iset(devPathBounds.fRight, devPathBounds.fTop, |
96 devClipBounds.fRight, devPathBounds.fBottom); | 99 devClipBounds.fRight, devPathBounds.fBottom); |
97 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 100 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
98 } | 101 } |
99 if (devClipBounds.fBottom > devPathBounds.fBottom) { | 102 if (devClipBounds.fBottom > devPathBounds.fBottom) { |
100 rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, | 103 rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, |
101 devClipBounds.fRight, devClipBounds.fBottom); | 104 devClipBounds.fRight, devClipBounds.fBottom); |
102 draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, i
nvert); | 105 draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), r
ect, invert); |
103 } | 106 } |
104 } | 107 } |
105 | 108 |
106 } | 109 } |
107 | 110 |
108 //////////////////////////////////////////////////////////////////////////////// | 111 //////////////////////////////////////////////////////////////////////////////// |
109 // return true on success; false on failure | 112 // return true on success; false on failure |
110 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { | 113 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { |
111 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRend
erer::onDrawPath"); | 114 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRend
erer::onDrawPath"); |
112 if (nullptr == fContext) { | 115 if (nullptr == fContext) { |
113 return false; | 116 return false; |
114 } | 117 } |
115 | 118 |
116 SkIRect devPathBounds, devClipBounds; | 119 SkIRect devPathBounds, devClipBounds; |
117 if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fPath, | 120 if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fClip, *args.fPat
h, |
118 *args.fViewMatrix, &devPathBounds, &devClipBou
nds)) { | 121 *args.fViewMatrix, &devPathBounds, &devClipBou
nds)) { |
119 if (args.fPath->isInverseFillType()) { | 122 if (args.fPath->isInverseFillType()) { |
120 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColo
r, | 123 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fCli
p, args.fColor, |
121 *args.fViewMatrix, devClipBounds, devPathBounds
); | 124 *args.fViewMatrix, devClipBounds, devPathBounds
); |
122 } | 125 } |
123 return true; | 126 return true; |
124 } | 127 } |
125 | 128 |
126 SkAutoTUnref<GrTexture> texture( | 129 SkAutoTUnref<GrTexture> texture( |
127 GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.f
Style, | 130 GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.f
Style, |
128 devPathBounds, | 131 devPathBounds, |
129 args.fAntiAlias, args.fViewMat
rix)); | 132 args.fAntiAlias, args.fViewMat
rix)); |
130 if (nullptr == texture) { | 133 if (nullptr == texture) { |
131 return false; | 134 return false; |
132 } | 135 } |
133 | 136 |
134 GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipeli
neBuilder, | 137 GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipeli
neBuilder, |
135 args.fColor, *args.fViewMatrix, dev
PathBounds); | 138 *args.fClip, args.fColor, *args.fVi
ewMatrix, |
| 139 devPathBounds); |
136 | 140 |
137 if (args.fPath->isInverseFillType()) { | 141 if (args.fPath->isInverseFillType()) { |
138 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *
args.fViewMatrix, | 142 draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, a
rgs.fColor, |
139 devClipBounds, devPathBounds); | 143 *args.fViewMatrix, devClipBounds, devPathBounds); |
140 } | 144 } |
141 | 145 |
142 return true; | 146 return true; |
143 } | 147 } |
OLD | NEW |