OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 // This test only works with the GPU backend. | 8 // This test only works with the GPU backend. |
9 | 9 |
10 #include "gm.h" | 10 #include "gm.h" |
11 | 11 |
12 #if SK_SUPPORT_GPU | 12 #if SK_SUPPORT_GPU |
13 | 13 |
14 #include "GrContext.h" | 14 #include "GrContext.h" |
15 #include "GrDefaultGeoProcFactory.h" | 15 #include "GrDefaultGeoProcFactory.h" |
16 #include "GrDrawContextPriv.h" | 16 #include "GrDrawContextPriv.h" |
17 #include "GrPathUtils.h" | 17 #include "GrPathUtils.h" |
18 #include "GrTest.h" | 18 #include "GrTest.h" |
19 #include "SkColorPriv.h" | 19 #include "SkColorPriv.h" |
20 #include "SkDevice.h" | 20 #include "SkDevice.h" |
21 #include "SkGeometry.h" | 21 #include "SkGeometry.h" |
22 #include "SkTLList.h" | 22 #include "SkTLList.h" |
23 | 23 |
24 #include "batches/GrTestBatch.h" | 24 #include "batches/GrTestBatch.h" |
25 #include "batches/GrVertexBatch.h" | 25 #include "batches/GrVertexBatch.h" |
26 | 26 |
27 #include "effects/GrConvexPolyEffect.h" | 27 #include "effects/GrConvexPolyEffect.h" |
28 | 28 |
| 29 /** outset rendered rect to visualize anti-aliased poly edges */ |
| 30 static SkRect outset(const SkRect& unsorted) { |
| 31 SkRect r = unsorted; |
| 32 r.outset(5.f, 5.f); |
| 33 return r; |
| 34 } |
| 35 |
| 36 /** sorts a rect */ |
| 37 static SkRect sorted_rect(const SkRect& unsorted) { |
| 38 SkRect r = unsorted; |
| 39 r.sort(); |
| 40 return r; |
| 41 } |
| 42 |
29 namespace skiagm { | 43 namespace skiagm { |
30 | 44 class PolyBoundsBatch : public GrTestBatch { |
31 class ConvexPolyTestBatch : public GrTestBatch { | |
32 public: | 45 public: |
33 DEFINE_BATCH_CLASS_ID | 46 DEFINE_BATCH_CLASS_ID |
34 struct Geometry : public GrTestBatch::Geometry { | |
35 SkRect fRect; | |
36 SkRect fBounds; // This will be == fRect, except fBounds must be sorted,
whereas fRect can | |
37 // be inverted | |
38 }; | |
39 | 47 |
40 const char* name() const override { return "ConvexPolyTestBatch"; } | 48 const char* name() const override { return "PolyBoundsBatch"; } |
41 | 49 |
42 static GrDrawBatch* Create(const GrGeometryProcessor* gp, const Geometry& ge
o) { | 50 PolyBoundsBatch(const SkRect& rect, GrColor color) |
43 return new ConvexPolyTestBatch(gp, geo); | 51 : INHERITED(ClassID(), outset(sorted_rect(rect)), color) |
| 52 , fRect(outset(rect)) { |
44 } | 53 } |
45 | 54 |
46 private: | 55 private: |
47 ConvexPolyTestBatch(const GrGeometryProcessor* gp, const Geometry& geo) | 56 void onPrepareDraws(Target* target) const override { |
48 : INHERITED(ClassID(), gp, geo.fBounds) | 57 using namespace GrDefaultGeoProcFactory; |
49 , fGeometry(geo) { | |
50 // Make sure any artifacts around the exterior of path are visible by us
ing overly | |
51 // conservative bounding geometry. | |
52 fGeometry.fBounds.outset(5.f, 5.f); | |
53 fGeometry.fRect.outset(5.f, 5.f); | |
54 } | |
55 | 58 |
56 Geometry* geoData(int index) override { | 59 Color color(this->color()); |
57 SkASSERT(0 == index); | 60 Coverage coverage(Coverage::kSolid_Type); |
58 return &fGeometry; | 61 LocalCoords localCoords(LocalCoords::kUnused_Type); |
59 } | 62 SkAutoTUnref<const GrGeometryProcessor> gp( |
| 63 GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatr
ix::I())); |
60 | 64 |
61 const Geometry* geoData(int index) const override { | 65 size_t vertexStride = gp->getVertexStride(); |
62 SkASSERT(0 == index); | |
63 return &fGeometry; | |
64 } | |
65 | |
66 void generateGeometry(Target* target) const override { | |
67 size_t vertexStride = this->geometryProcessor()->getVertexStride(); | |
68 SkASSERT(vertexStride == sizeof(SkPoint)); | 66 SkASSERT(vertexStride == sizeof(SkPoint)); |
69 QuadHelper helper; | 67 QuadHelper helper; |
70 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, vertexSt
ride, 1)); | 68 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, vertexSt
ride, 1)); |
71 if (!verts) { | 69 if (!verts) { |
72 return; | 70 return; |
73 } | 71 } |
74 | 72 |
75 fGeometry.fRect.toQuad(verts); | 73 fRect.toQuad(verts); |
76 | 74 |
77 helper.recordDraw(target); | 75 helper.recordDraw(target, gp); |
78 } | 76 } |
79 | 77 |
80 Geometry fGeometry; | 78 SkRect fRect; |
81 | 79 |
82 typedef GrTestBatch INHERITED; | 80 typedef GrTestBatch INHERITED; |
83 }; | 81 }; |
84 | 82 |
85 /** | 83 /** |
86 * This GM directly exercises a GrProcessor that draws convex polygons. | 84 * This GM directly exercises a GrProcessor that draws convex polygons. |
87 */ | 85 */ |
88 class ConvexPolyEffect : public GM { | 86 class ConvexPolyEffect : public GM { |
89 public: | 87 public: |
90 ConvexPolyEffect() { | 88 ConvexPolyEffect() { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 // vertically/horizontally thin rects that don't cover pixel centers | 147 // vertically/horizontally thin rects that don't cover pixel centers |
150 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f)); | 148 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f)); |
151 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f)); | 149 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f)); |
152 // small in x and y | 150 // small in x and y |
153 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f)); | 151 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f)); |
154 // inverted in x and y | 152 // inverted in x and y |
155 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f)); | 153 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f)); |
156 } | 154 } |
157 | 155 |
158 void onDraw(SkCanvas* canvas) override { | 156 void onDraw(SkCanvas* canvas) override { |
159 using namespace GrDefaultGeoProcFactory; | |
160 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); | 157 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); |
161 if (nullptr == rt) { | 158 if (nullptr == rt) { |
162 skiagm::GM::DrawGpuOnlyMessage(canvas); | 159 skiagm::GM::DrawGpuOnlyMessage(canvas); |
163 return; | 160 return; |
164 } | 161 } |
165 GrContext* context = rt->getContext(); | 162 GrContext* context = rt->getContext(); |
166 if (nullptr == context) { | 163 if (nullptr == context) { |
167 return; | 164 return; |
168 } | 165 } |
169 | 166 |
170 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt)); | 167 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt)); |
171 if (!drawContext) { | 168 if (!drawContext) { |
172 return; | 169 return; |
173 } | 170 } |
174 | 171 |
175 Color color(0xff000000); | |
176 Coverage coverage(Coverage::kSolid_Type); | |
177 LocalCoords localCoords(LocalCoords::kUnused_Type); | |
178 SkAutoTUnref<const GrGeometryProcessor> gp( | |
179 GrDefaultGeoProcFactory::Create(color, coverage, localCoords, Sk
Matrix::I())); | |
180 | |
181 SkScalar y = 0; | 172 SkScalar y = 0; |
182 static const SkScalar kDX = 12.f; | 173 static const SkScalar kDX = 12.f; |
183 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart); | 174 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart); |
184 iter.get(); | 175 iter.get(); |
185 iter.next()) { | 176 iter.next()) { |
186 const SkPath* path = iter.get(); | 177 const SkPath* path = iter.get(); |
187 SkScalar x = 0; | 178 SkScalar x = 0; |
188 | 179 |
189 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) { | 180 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) { |
190 const SkMatrix m = SkMatrix::MakeTrans(x, y); | 181 const SkMatrix m = SkMatrix::MakeTrans(x, y); |
191 SkPath p; | 182 SkPath p; |
192 path->transform(m, &p); | 183 path->transform(m, &p); |
193 | 184 |
194 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et; | 185 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et; |
195 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(
edgeType, p)); | 186 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(
edgeType, p)); |
196 if (!fp) { | 187 if (!fp) { |
197 continue; | 188 continue; |
198 } | 189 } |
199 | 190 |
200 GrPipelineBuilder pipelineBuilder; | 191 GrPipelineBuilder pipelineBuilder; |
201 pipelineBuilder.setXPFactory( | 192 pipelineBuilder.setXPFactory( |
202 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref
(); | 193 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref
(); |
203 pipelineBuilder.addCoverageFragmentProcessor(fp); | 194 pipelineBuilder.addCoverageFragmentProcessor(fp); |
204 pipelineBuilder.setRenderTarget(rt); | 195 pipelineBuilder.setRenderTarget(rt); |
205 | 196 |
206 ConvexPolyTestBatch::Geometry geometry; | 197 SkAutoTUnref<GrDrawBatch> batch(new PolyBoundsBatch(p.getBounds(
), 0xff000000)); |
207 geometry.fColor = color.fColor; | |
208 geometry.fRect = p.getBounds(); | |
209 geometry.fBounds = p.getBounds(); | |
210 | |
211 SkAutoTUnref<GrDrawBatch> batch(ConvexPolyTestBatch::Create(gp,
geometry)); | |
212 | 198 |
213 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBui
lder, batch); | 199 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBui
lder, batch); |
214 | 200 |
215 x += SkScalarCeilToScalar(path->getBounds().width() + kDX); | 201 x += SkScalarCeilToScalar(path->getBounds().width() + kDX); |
216 } | 202 } |
217 | 203 |
218 // Draw AA and non AA paths using normal API for reference. | 204 // Draw AA and non AA paths using normal API for reference. |
219 canvas->save(); | 205 canvas->save(); |
220 canvas->translate(x, y); | 206 canvas->translate(x, y); |
221 SkPaint paint; | 207 SkPaint paint; |
(...skipping 20 matching lines...) Expand all Loading... |
242 if (!fp) { | 228 if (!fp) { |
243 continue; | 229 continue; |
244 } | 230 } |
245 | 231 |
246 GrPipelineBuilder pipelineBuilder; | 232 GrPipelineBuilder pipelineBuilder; |
247 pipelineBuilder.setXPFactory( | 233 pipelineBuilder.setXPFactory( |
248 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref
(); | 234 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref
(); |
249 pipelineBuilder.addCoverageFragmentProcessor(fp); | 235 pipelineBuilder.addCoverageFragmentProcessor(fp); |
250 pipelineBuilder.setRenderTarget(rt); | 236 pipelineBuilder.setRenderTarget(rt); |
251 | 237 |
252 ConvexPolyTestBatch::Geometry geometry; | 238 SkAutoTUnref<GrDrawBatch> batch(new PolyBoundsBatch(rect, 0xff00
0000)); |
253 geometry.fColor = color.fColor; | |
254 geometry.fRect = rect; | |
255 geometry.fBounds = rect; | |
256 geometry.fBounds.sort(); | |
257 | |
258 SkAutoTUnref<GrDrawBatch> batch(ConvexPolyTestBatch::Create(gp,
geometry)); | |
259 | 239 |
260 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBui
lder, batch); | 240 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBui
lder, batch); |
261 | 241 |
262 x += SkScalarCeilToScalar(rect.width() + kDX); | 242 x += SkScalarCeilToScalar(rect.width() + kDX); |
263 } | 243 } |
264 | 244 |
265 // Draw rect without and with AA using normal API for reference | 245 // Draw rect without and with AA using normal API for reference |
266 canvas->save(); | 246 canvas->save(); |
267 canvas->translate(x, y); | 247 canvas->translate(x, y); |
268 SkPaint paint; | 248 SkPaint paint; |
(...skipping 13 matching lines...) Expand all Loading... |
282 PathList fPaths; | 262 PathList fPaths; |
283 RectList fRects; | 263 RectList fRects; |
284 | 264 |
285 typedef GM INHERITED; | 265 typedef GM INHERITED; |
286 }; | 266 }; |
287 | 267 |
288 DEF_GM(return new ConvexPolyEffect;) | 268 DEF_GM(return new ConvexPolyEffect;) |
289 } | 269 } |
290 | 270 |
291 #endif | 271 #endif |
OLD | NEW |