| 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 |