OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2014 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 "GrAAConcavePathRenderer.h" |
| 9 |
| 10 #include "GrDefaultGeoProcFactory.h" |
| 11 #include "GrPathUtils.h" |
| 12 #include "SkString.h" |
| 13 #include "SkStrokeRec.h" |
| 14 #include "SkTLazy.h" |
| 15 #include "SkTraceEvent.h" |
| 16 #include "SkScan.h" |
| 17 |
| 18 #include "batches/GrVertexBatch.h" |
| 19 #include "GrBatchFlushState.h" |
| 20 |
| 21 #include <stdio.h> // FIXME |
| 22 |
| 23 class AAConcavePathBatch : public GrVertexBatch { |
| 24 public: |
| 25 struct Geometry { |
| 26 GrColor fColor; |
| 27 SkMatrix fViewMatrix; |
| 28 SkPath fPath; |
| 29 SkIRect fClipBounds; |
| 30 bool fAntiAlias; |
| 31 }; |
| 32 |
| 33 static GrDrawBatch* Create(const Geometry& geometry) { |
| 34 return SkNEW_ARGS(AAConcavePathBatch, (geometry)); |
| 35 } |
| 36 |
| 37 const char* name() const override { return "AAConcavePathBatch"; } |
| 38 |
| 39 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 40 out->setKnownFourComponents(fGeometry.fColor); |
| 41 } |
| 42 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 43 out->setUnknownSingleComponent(); |
| 44 } |
| 45 |
| 46 private: |
| 47 void initBatchTracker(const GrPipelineOptimizations& opt) override { |
| 48 // Handle any color overrides |
| 49 if (!opt.readsColor()) { |
| 50 fGeometry.fColor = GrColor_ILLEGAL; |
| 51 } |
| 52 opt.getOverrideColorIfSet(&fGeometry.fColor); |
| 53 |
| 54 fPipelineInfo = opt; |
| 55 } |
| 56 AAConcavePathBatch(const Geometry& geometry) { |
| 57 this->initClassID<AAConcavePathBatch>(); |
| 58 fGeometry = geometry; |
| 59 geometry.fViewMatrix.mapRect(&fBounds, geometry.fPath.getBounds()); |
| 60 } |
| 61 void onPrepareDraws(Target* target) override; |
| 62 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } |
| 63 |
| 64 Geometry fGeometry; |
| 65 GrPipelineOptimizations fPipelineInfo; |
| 66 }; |
| 67 |
| 68 GrAAConcavePathRenderer::GrAAConcavePathRenderer() { |
| 69 } |
| 70 |
| 71 |
| 72 GrPathRenderer::StencilSupport GrAAConcavePathRenderer::onGetStencilSupport( |
| 73 const SkPath&, |
| 74 const GrStrokeInfo&)
const { |
| 75 return GrPathRenderer::kNoSupport_StencilSupport; |
| 76 } |
| 77 |
| 78 bool GrAAConcavePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
| 79 const GrStrokeInfo& stroke = *args.fStroke; |
| 80 return stroke.isFillStyle(); |
| 81 } |
| 82 |
| 83 bool GrAAConcavePathRenderer::onDrawPath(const DrawPathArgs& args) { |
| 84 GrDrawTarget* target = args.fTarget; |
| 85 |
| 86 // compute bounds as intersection of rt size, clip, and path |
| 87 const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget(); |
| 88 if (NULL == rt) { |
| 89 return false; |
| 90 } |
| 91 |
| 92 SkIRect clipBoundsI; |
| 93 args.fPipelineBuilder->clip().getConservativeBounds(rt, &clipBoundsI); |
| 94 AAConcavePathBatch::Geometry geometry; |
| 95 geometry.fColor = args.fColor; |
| 96 geometry.fPath = *args.fPath; |
| 97 geometry.fViewMatrix = *args.fViewMatrix; |
| 98 geometry.fClipBounds = clipBoundsI; |
| 99 geometry.fAntiAlias = args.fAntiAlias; |
| 100 SkAutoTUnref<GrDrawBatch> batch(AAConcavePathBatch::Create(geometry)); |
| 101 target->drawBatch(*args.fPipelineBuilder, batch.get()); |
| 102 |
| 103 return true; |
| 104 } |
| 105 |
| 106 void AAConcavePathBatch::onPrepareDraws(Target* target) { |
| 107 const SkPath& path = fGeometry.fPath; |
| 108 const SkIRect clipRect = fGeometry.fClipBounds; |
| 109 const GrColor color = fGeometry.fColor; |
| 110 const SkMatrix& viewMatrix = fGeometry.fViewMatrix; |
| 111 bool antiAlias = fGeometry.fAntiAlias; |
| 112 SkTDArray<SkPoint> points; |
| 113 SkPath deviceSpacePath; |
| 114 path.transform(viewMatrix, &deviceSpacePath); |
| 115 SkScan::PathToTriangles(deviceSpacePath, clipRect, antiAlias, &points); |
| 116 if (0 == points.count()) { |
| 117 return; |
| 118 } |
| 119 const GrVertexBuffer* vertexBuffer; |
| 120 int vertexStride = sizeof(SkPoint); |
| 121 int firstVertex; |
| 122 void* verts = target->makeVertexSpace(vertexStride, points.count(), &vertexB
uffer, &firstVertex); |
| 123 if (!verts) { |
| 124 return; |
| 125 } |
| 126 |
| 127 // FIXME: avoid this memcpy by asking SkScan for worst-case size? |
| 128 memcpy(verts, points.begin(), points.count() * sizeof(SkPoint)); |
| 129 |
| 130 // FIXME: pass devBounds here? |
| 131 uint8_t coverage = 0xFF; |
| 132 using namespace GrDefaultGeoProcFactory; |
| 133 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ? LocalCoords::kUse
Position_Type |
| 134 : LocalCoords::kUnu
sed_Type); |
| 135 |
| 136 GrPrimitiveType primitiveType = SkScan::gWireframe ? kLines_GrPrimitiveType
: kTriangles_GrPrimitiveType; |
| 137 SkAutoTUnref<const GrGeometryProcessor> gp( |
| 138 GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatr
ix::I())); |
| 139 |
| 140 target->initDraw(gp, this->pipeline()); |
| 141 GrVertices vertices; |
| 142 vertices.init(primitiveType, vertexBuffer, firstVertex, points.count()); |
| 143 |
| 144 target->draw(vertices); |
| 145 } |
OLD | NEW |