• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <array>
12 #include "include/core/SkPath.h"
13 #include "src/gpu/GrCaps.h"
14 #include "src/gpu/GrGeometryProcessor.h"
15 #include "src/gpu/GrPipeline.h"
16 #include "src/gpu/ccpr/GrOctoBounds.h"
17 
18 class GrCCPathCacheEntry;
19 class GrCCPerFlushResources;
20 class GrOnFlushResourceProvider;
21 class GrOpFlushState;
22 
23 /**
24  * This class draws AA paths using the coverage count masks produced by GrCCCoverageProcessor.
25  *
26  * Paths are drawn as bloated octagons, and coverage is derived from the coverage count mask and
27  * fill rule.
28  *
29  * To draw paths, the caller must set up an instance buffer as detailed below, then call drawPaths()
30  * providing its own instance buffer alongside the buffers found by calling FindIndexBuffer/
31  * FindVertexBuffer.
32  */
33 class GrCCPathProcessor : public GrGeometryProcessor {
34 public:
35     struct Instance {
36         SkRect fDevBounds;  // "right < left" indicates even-odd fill type.
37         SkRect fDevBounds45;  // Bounding box in "| 1  -1 | * devCoords" space. See GrOctoBounds.
38                               //                  | 1   1 |
39         SkIVector fDevToAtlasOffset;  // Translation from device space to location in atlas.
40         uint64_t fColor;  // Color always stored as 4 x fp16
41 
42         void set(const GrOctoBounds&, const SkIVector& devToAtlasOffset, uint64_t, GrFillRule);
43         void set(const GrCCPathCacheEntry&, const SkIVector& shift, uint64_t, GrFillRule);
44     };
45 
46     static_assert(4 * 12 == sizeof(Instance));
47 
48     static sk_sp<const GrGpuBuffer> FindVertexBuffer(GrOnFlushResourceProvider*);
49     static sk_sp<const GrGpuBuffer> FindIndexBuffer(GrOnFlushResourceProvider*);
50 
51     enum class CoverageMode : bool {
52         kCoverageCount,
53         kLiteral
54     };
55 
GetColorTypeFromCoverageMode(CoverageMode mode)56     static GrColorType GetColorTypeFromCoverageMode(CoverageMode mode) {
57         return mode == CoverageMode::kCoverageCount ? GrColorType::kAlpha_F16
58             : GrColorType::kAlpha_8;
59     }
60 
61     GrCCPathProcessor(CoverageMode, const GrTexture* atlasTexture, const GrSwizzle&,
62                       GrSurfaceOrigin atlasOrigin,
63                       const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
64 
name()65     const char* name() const override { return "GrCCPathProcessor"; }
getGLSLProcessorKey(const GrShaderCaps &,GrProcessorKeyBuilder * b)66     void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
67         b->add32((uint32_t)fCoverageMode);
68     }
69     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
70 
71     void drawPaths(GrOpFlushState*, const GrPipeline&, const GrPipeline::FixedDynamicState*,
72                    const GrCCPerFlushResources&, int baseInstance, int endInstance,
73                    const SkRect& bounds) const;
74 
75 private:
onTextureSampler(int)76     const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; }
77 
78     const CoverageMode fCoverageMode;
79     const TextureSampler fAtlasAccess;
80     SkISize fAtlasDimensions;
81     GrSurfaceOrigin fAtlasOrigin;
82 
83     SkMatrix fLocalMatrix;
84     static constexpr Attribute kInstanceAttribs[] = {
85             {"devbounds", kFloat4_GrVertexAttribType, kFloat4_GrSLType},
86             {"devbounds45", kFloat4_GrVertexAttribType, kFloat4_GrSLType},
87             {"dev_to_atlas_offset", kInt2_GrVertexAttribType, kInt2_GrSLType},
88             {"color", kHalf4_GrVertexAttribType, kHalf4_GrSLType}
89     };
90     static constexpr int kColorAttribIdx = 3;
91     static constexpr Attribute kCornersAttrib =
92             {"corners", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
93 
94     class Impl;
95 
96     typedef GrGeometryProcessor INHERITED;
97 };
98 
set(const GrOctoBounds & octoBounds,const SkIVector & devToAtlasOffset,uint64_t color,GrFillRule fillRule)99 inline void GrCCPathProcessor::Instance::set(
100         const GrOctoBounds& octoBounds, const SkIVector& devToAtlasOffset, uint64_t color,
101         GrFillRule fillRule) {
102     if (GrFillRule::kNonzero == fillRule) {
103         // We cover "nonzero" paths with clockwise triangles, which is the default result from
104         // normal octo bounds.
105         fDevBounds = octoBounds.bounds();
106         fDevBounds45 = octoBounds.bounds45();
107     } else {
108         // We cover "even/odd" paths with counterclockwise triangles. Here we reorder the bounding
109         // box vertices so the output is flipped horizontally.
110         fDevBounds.setLTRB(
111                 octoBounds.right(), octoBounds.top(), octoBounds.left(), octoBounds.bottom());
112         fDevBounds45.setLTRB(
113                 octoBounds.bottom45(), octoBounds.right45(), octoBounds.top45(),
114                 octoBounds.left45());
115     }
116     fDevToAtlasOffset = devToAtlasOffset;
117     fColor = color;
118 }
119 
120 #endif
121