1 /* 2 * Copyright 2017 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 #ifndef GrCCPathProcessor_DEFINED 9 #define GrCCPathProcessor_DEFINED 10 11 #include "GrCaps.h" 12 #include "GrGeometryProcessor.h" 13 #include "SkPath.h" 14 #include <array> 15 16 class GrOnFlushResourceProvider; 17 18 /** 19 * This class draws AA paths using the coverage count masks produced by GrCCCoverageProcessor. 20 * 21 * Paths are drawn as bloated octagons, and coverage is derived from the coverage count mask and 22 * fill rule. 23 * 24 * The caller must set up an instance buffer as detailed below, then draw indexed-instanced 25 * meshes using the buffers and parameters provided by this class. 26 */ 27 class GrCCPathProcessor : public GrGeometryProcessor { 28 public: 29 enum class InstanceAttribs { 30 kDevBounds, 31 kDevBounds45, 32 kViewMatrix, // FIXME: This causes a lot of duplication. It could move to a texel buffer. 33 kViewTranslate, 34 kAtlasOffset, 35 kColor 36 }; 37 static constexpr int kNumInstanceAttribs = 1 + (int)InstanceAttribs::kColor; 38 39 struct Instance { 40 SkRect fDevBounds; 41 SkRect fDevBounds45; // Bounding box in "| 1 -1 | * devCoords" space. 42 // | 1 1 | 43 std::array<float, 4> fViewMatrix; // {kScaleX, kSkewy, kSkewX, kScaleY} 44 std::array<float, 2> fViewTranslate; 45 std::array<int16_t, 2> fAtlasOffset; 46 uint32_t fColor; 47 48 GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); 49 }; 50 51 GR_STATIC_ASSERT(4 * 16 == sizeof(Instance)); 52 53 static GrPrimitiveType MeshPrimitiveType(const GrCaps& caps) { 54 return caps.usePrimitiveRestart() ? GrPrimitiveType::kTriangleStrip 55 : GrPrimitiveType::kTriangles; 56 } 57 static sk_sp<const GrBuffer> FindVertexBuffer(GrOnFlushResourceProvider*); 58 static sk_sp<const GrBuffer> FindIndexBuffer(GrOnFlushResourceProvider*); 59 static int NumIndicesPerInstance(const GrCaps&); 60 61 GrCCPathProcessor(GrResourceProvider*, sk_sp<GrTextureProxy> atlas, SkPath::FillType); 62 63 const char* name() const override { return "GrCCPathProcessor"; } 64 const GrSurfaceProxy* atlasProxy() const { return fAtlasAccess.proxy(); } 65 const GrTexture* atlas() const { return fAtlasAccess.peekTexture(); } 66 SkPath::FillType fillType() const { return fFillType; } 67 const Attribute& getInstanceAttrib(InstanceAttribs attribID) const { 68 const Attribute& attrib = this->getAttrib((int)attribID); 69 SkASSERT(Attribute::InputRate::kPerInstance == attrib.fInputRate); 70 return attrib; 71 } 72 const Attribute& getEdgeNormsAttrib() const { 73 SkASSERT(1 + kNumInstanceAttribs == this->numAttribs()); 74 const Attribute& attrib = this->getAttrib(kNumInstanceAttribs); 75 SkASSERT(Attribute::InputRate::kPerVertex == attrib.fInputRate); 76 return attrib; 77 } 78 79 void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 80 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; 81 82 private: 83 const SkPath::FillType fFillType; 84 const TextureSampler fAtlasAccess; 85 86 typedef GrGeometryProcessor INHERITED; 87 }; 88 89 #endif 90