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