• 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 "ops/GrMeshDrawOp.h"
12 #include "text/GrTextBlob.h"
13 #include "text/GrDistanceFieldAdjustTable.h"
14 
15 class SkAtlasTextTarget;
16 class GrContext;
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     typedef GrTextBlob Blob;
32     struct Geometry {
33         SkMatrix    fViewMatrix;
34         SkIRect     fClipRect;
35         Blob*       fBlob;
36         SkScalar    fX;
37         SkScalar    fY;
38         uint16_t    fRun;
39         uint16_t    fSubRun;
40         SkPMColor4f fColor;
41     };
42 
43     static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrContext* context,
44                                                      GrPaint&& paint,
45                                                      GrMaskFormat maskFormat,
46                                                      int glyphCount,
47                                                      bool needsTransform);
48 
49     static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
50             GrContext* context,
51             GrPaint&& paint,
52             int glyphCount,
53             const GrDistanceFieldAdjustTable* distanceAdjustTable,
54             bool useGammaCorrectDistanceTable,
55             SkColor luminanceColor,
56             const SkSurfaceProps& props,
57             bool isAntiAliased,
58             bool useLCD);
59 
60     // To avoid even the initial copy of the struct, we have a getter for the first item which
61     // is used to seed the op with its initial geometry.  After seeding, the client should call
62     // init() so the op can initialize itself
geometry()63     Geometry& geometry() { return fGeoData[0]; }
64 
65     /** Called after this->geometry() has been configured. */
66     void init();
67 
name()68     const char* name() const override { return "AtlasTextOp"; }
69 
70     void visitProxies(const VisitProxyFunc& func, VisitorType) const override;
71 
72 #ifdef SK_DEBUG
73     SkString dumpInfo() const override;
74 #endif
75 
76     FixedFunctionFlags fixedFunctionFlags() const override;
77 
78     GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip) override;
79 
80     enum MaskType {
81         kGrayscaleCoverageMask_MaskType,
82         kLCDCoverageMask_MaskType,
83         kColorBitmapMask_MaskType,
84         kAliasedDistanceField_MaskType,
85         kGrayscaleDistanceField_MaskType,
86         kLCDDistanceField_MaskType,
87         kLCDBGRDistanceField_MaskType,
88     };
89 
maskType()90     MaskType maskType() const { return fMaskType; }
91 
92     void finalizeForTextTarget(uint32_t color, const GrCaps&);
93     void executeForTextTarget(SkAtlasTextTarget*);
94 
95 private:
96     friend class GrOpMemoryPool; // for ctor
97 
98     // The minimum number of Geometry we will try to allocate.
99     static constexpr auto kMinGeometryAllocated = 12;
100 
GrAtlasTextOp(GrPaint && paint)101     GrAtlasTextOp(GrPaint&& paint)
102             : INHERITED(ClassID())
103             , fGeoDataAllocSize(kMinGeometryAllocated)
104             , fProcessors(std::move(paint)) {}
105 
106     struct FlushInfo {
107         sk_sp<const GrBuffer> fVertexBuffer;
108         sk_sp<const GrBuffer> fIndexBuffer;
109         sk_sp<GrGeometryProcessor> fGeometryProcessor;
110         const GrPipeline* fPipeline;
111         GrPipeline::FixedDynamicState* fFixedDynamicState;
112         int fGlyphsToFlush;
113         int fVertexOffset;
114     };
115 
116     void onPrepareDraws(Target*) override;
117 
maskFormat()118     GrMaskFormat maskFormat() const {
119         switch (fMaskType) {
120             case kLCDCoverageMask_MaskType:
121                 return kA565_GrMaskFormat;
122             case kColorBitmapMask_MaskType:
123                 return kARGB_GrMaskFormat;
124             case kGrayscaleCoverageMask_MaskType:
125             case kAliasedDistanceField_MaskType:
126             case kGrayscaleDistanceField_MaskType:
127             case kLCDDistanceField_MaskType:
128             case kLCDBGRDistanceField_MaskType:
129                 return kA8_GrMaskFormat;
130         }
131         return kA8_GrMaskFormat;  // suppress warning
132     }
133 
usesDistanceFields()134     bool usesDistanceFields() const {
135         return kAliasedDistanceField_MaskType == fMaskType ||
136                kGrayscaleDistanceField_MaskType == fMaskType ||
137                kLCDDistanceField_MaskType == fMaskType ||
138                kLCDBGRDistanceField_MaskType == fMaskType;
139     }
140 
isLCD()141     bool isLCD() const {
142         return kLCDCoverageMask_MaskType == fMaskType ||
143                kLCDDistanceField_MaskType == fMaskType ||
144                kLCDBGRDistanceField_MaskType == fMaskType;
145     }
146 
147     inline void flush(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, const GrCaps& caps) override;
154 
155     sk_sp<GrGeometryProcessor> setupDfProcessor(const GrShaderCaps& caps,
156                                                 const sk_sp<GrTextureProxy>* proxies,
157                                                 unsigned int numActiveProxies) const;
158 
159     SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
160     int fGeoDataAllocSize;
161     GrProcessorSet fProcessors;
162     struct {
163         uint32_t fUsesLocalCoords : 1;
164         uint32_t fUseGammaCorrectDistanceTable : 1;
165         uint32_t fNeedsGlyphTransform : 1;
166     };
167     int fGeoCount;
168     int fNumGlyphs;
169     MaskType fMaskType;
170     // Distance field properties
171     sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
172     SkColor fLuminanceColor;
173     uint32_t fDFGPFlags = 0;
174 
175     typedef GrMeshDrawOp INHERITED;
176 };
177 
178 #endif
179