• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 GrAtlasTextOp_DEFINED
9 #define GrAtlasTextOp_DEFINED
10 
11 #include "src/gpu/ops/GrMeshDrawOp.h"
12 #include "src/gpu/text/GrDistanceFieldAdjustTable.h"
13 #include "src/gpu/text/GrTextBlob.h"
14 
15 class GrRecordingContext;
16 class SkAtlasTextTarget;
17 
18 class GrAtlasTextOp final : public GrMeshDrawOp {
19 public:
20     DEFINE_OP_CLASS_ID
21 
~GrAtlasTextOp()22     ~GrAtlasTextOp() override {
23         for (int i = 0; i < fGeoCount; i++) {
24             fGeoData[i].fBlob->unref();
25         }
26     }
27 
28     static const int kVerticesPerGlyph = GrTextBlob::kVerticesPerGlyph;
29     static const int kIndicesPerGlyph = 6;
30 
31     struct Geometry {
32         SkMatrix    fDrawMatrix;
33         SkIRect     fClipRect;
34         GrTextBlob* fBlob;
35         SkPoint     fDrawOrigin;
36         GrTextBlob::SubRun* fSubRunPtr;
37         SkPMColor4f fColor;
38     };
39 
40     static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrRecordingContext*,
41                                                      GrPaint&&,
42                                                      GrMaskFormat,
43                                                      int glyphCount,
44                                                      bool needsTransform);
45 
46     static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
47             GrRecordingContext*,
48             GrPaint&&,
49             int glyphCount,
50             const GrDistanceFieldAdjustTable*,
51             bool useGammaCorrectDistanceTable,
52             SkColor luminanceColor,
53             const SkSurfaceProps&,
54             bool isAntiAliased,
55             bool useLCD);
56 
57     // To avoid even the initial copy of the struct, we have a getter for the first item which
58     // is used to seed the op with its initial geometry.  After seeding, the client should call
59     // init() so the op can initialize itself
geometry()60     Geometry& geometry() { return fGeoData[0]; }
61 
62     /** Called after this->geometry() has been configured. */
63     void init();
64 
name()65     const char* name() const override { return "AtlasTextOp"; }
66 
67     void visitProxies(const VisitProxyFunc& func) const override;
68 
69 #ifdef SK_DEBUG
70     SkString dumpInfo() const override;
71 #endif
72 
73     FixedFunctionFlags fixedFunctionFlags() const override;
74 
75     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
76                                       bool hasMixedSampledCoverage, GrClampType) override;
77 
78     enum MaskType {
79         kGrayscaleCoverageMask_MaskType,
80         kLCDCoverageMask_MaskType,
81         kColorBitmapMask_MaskType,
82         kAliasedDistanceField_MaskType,
83         kGrayscaleDistanceField_MaskType,
84         kLCDDistanceField_MaskType,
85         kLCDBGRDistanceField_MaskType,
86     };
87 
maskType()88     MaskType maskType() const { return fMaskType; }
89 
90     void finalizeForTextTarget(uint32_t color, const GrCaps&);
91     void executeForTextTarget(SkAtlasTextTarget*);
92 
93 private:
94     friend class GrOpMemoryPool; // for ctor
95 
96     // The minimum number of Geometry we will try to allocate.
97     static constexpr auto kMinGeometryAllocated = 12;
98 
GrAtlasTextOp(GrPaint && paint)99     GrAtlasTextOp(GrPaint&& paint)
100             : INHERITED(ClassID())
101             , fGeoDataAllocSize(kMinGeometryAllocated)
102             , fProcessors(std::move(paint)) {}
103 
104     struct FlushInfo {
105         sk_sp<const GrBuffer> fVertexBuffer;
106         sk_sp<const GrBuffer> fIndexBuffer;
107         GrGeometryProcessor*  fGeometryProcessor;
108         GrPipeline::FixedDynamicState* fFixedDynamicState;
109         int fGlyphsToFlush = 0;
110         int fVertexOffset = 0;
111         int fNumDraws = 0;
112     };
113 
114     void onPrepareDraws(Target*) override;
115     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
116 
maskFormat()117     GrMaskFormat maskFormat() const {
118         switch (fMaskType) {
119             case kLCDCoverageMask_MaskType:
120                 return kA565_GrMaskFormat;
121             case kColorBitmapMask_MaskType:
122                 return kARGB_GrMaskFormat;
123             case kGrayscaleCoverageMask_MaskType:
124             case kAliasedDistanceField_MaskType:
125             case kGrayscaleDistanceField_MaskType:
126             case kLCDDistanceField_MaskType:
127             case kLCDBGRDistanceField_MaskType:
128                 return kA8_GrMaskFormat;
129         }
130         return kA8_GrMaskFormat;  // suppress warning
131     }
132 
usesDistanceFields()133     bool usesDistanceFields() const {
134         return kAliasedDistanceField_MaskType == fMaskType ||
135                kGrayscaleDistanceField_MaskType == fMaskType ||
136                kLCDDistanceField_MaskType == fMaskType ||
137                kLCDBGRDistanceField_MaskType == fMaskType;
138     }
139 
isLCD()140     bool isLCD() const {
141         return kLCDCoverageMask_MaskType == fMaskType ||
142                kLCDDistanceField_MaskType == fMaskType ||
143                kLCDBGRDistanceField_MaskType == fMaskType;
144     }
145 
146     inline void createDrawForGeneratedGlyphs(
147             GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
148 
color()149     const SkPMColor4f& color() const { SkASSERT(fGeoCount > 0); return fGeoData[0].fColor; }
usesLocalCoords()150     bool usesLocalCoords() const { return fUsesLocalCoords; }
numGlyphs()151     int numGlyphs() const { return fNumGlyphs; }
152 
153     CombineResult onCombineIfPossible(GrOp* t, GrRecordingContext::Arenas*,
154                                       const GrCaps& caps) override;
155 
156     GrGeometryProcessor* setupDfProcessor(SkArenaAlloc* arena,
157                                           const GrShaderCaps& caps,
158                                           const GrSurfaceProxyView* views,
159                                           unsigned int numActiveViews) const;
160 
161     SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
162     int fGeoDataAllocSize;
163     GrProcessorSet fProcessors;
164     struct {
165         uint32_t fUsesLocalCoords : 1;
166         uint32_t fUseGammaCorrectDistanceTable : 1;
167         uint32_t fNeedsGlyphTransform : 1;
168     };
169     int fGeoCount;
170     int fNumGlyphs;
171     MaskType fMaskType;
172     // Distance field properties
173     sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
174     SkColor fLuminanceColor;
175     uint32_t fDFGPFlags = 0;
176 
177     typedef GrMeshDrawOp INHERITED;
178 };
179 
180 #endif
181