OLD | NEW |
---|---|
(Empty) | |
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 | |
robertphillips
2015/11/19 22:24:44
#ifndef ...
| |
8 #include "batches/GrVertexBatch.h" | |
9 | |
10 #include "GrAtlasTextContext.h" | |
11 | |
12 class GrAtlasTextBatch : public GrVertexBatch { | |
13 public: | |
14 DEFINE_BATCH_CLASS_ID | |
15 static const size_t kLCDTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); | |
16 | |
17 // position + local coord | |
18 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); | |
19 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + si zeof(SkIPoint16); | |
20 static const int kVerticesPerGlyph = 4; | |
21 static const int kIndicesPerGlyph = 6; | |
22 | |
23 typedef GrAtlasTextContext::DistanceAdjustTable DistanceAdjustTable; | |
24 typedef GrAtlasTextBlob Blob; | |
25 typedef Blob::Run Run; | |
26 typedef Run::SubRunInfo TextInfo; | |
27 struct Geometry { | |
28 Blob* fBlob; | |
29 int fRun; | |
30 int fSubRun; | |
31 GrColor fColor; | |
32 SkScalar fTransX; | |
33 SkScalar fTransY; | |
34 }; | |
35 | |
36 static GrAtlasTextBatch* CreateBitmap(GrMaskFormat maskFormat, int glyphCoun t, | |
37 GrBatchFontCache* fontCache) { | |
38 GrAtlasTextBatch* batch = new GrAtlasTextBatch; | |
39 | |
40 batch->fFontCache = fontCache; | |
41 switch (maskFormat) { | |
42 case kA8_GrMaskFormat: | |
43 batch->fMaskType = kGrayscaleCoverageMask_MaskType; | |
44 break; | |
45 case kA565_GrMaskFormat: | |
46 batch->fMaskType = kLCDCoverageMask_MaskType; | |
47 break; | |
48 case kARGB_GrMaskFormat: | |
49 batch->fMaskType = kColorBitmapMask_MaskType; | |
50 break; | |
51 } | |
52 batch->fBatch.fNumGlyphs = glyphCount; | |
53 batch->fGeoCount = 1; | |
54 batch->fFilteredColor = 0; | |
55 batch->fFontCache = fontCache; | |
56 batch->fUseBGR = false; | |
57 return batch; | |
58 } | |
59 | |
60 static GrAtlasTextBatch* CreateDistanceField(int glyphCount, GrBatchFontCach e* fontCache, | |
61 const DistanceAdjustTable* dist anceAdjustTable, | |
62 SkColor filteredColor, bool isL CD, | |
63 bool useBGR) { | |
64 GrAtlasTextBatch* batch = new GrAtlasTextBatch; | |
65 | |
66 batch->fFontCache = fontCache; | |
67 batch->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistan ceField_MaskType; | |
68 batch->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable)); | |
69 batch->fFilteredColor = filteredColor; | |
70 batch->fUseBGR = useBGR; | |
71 batch->fBatch.fNumGlyphs = glyphCount; | |
72 batch->fGeoCount = 1; | |
73 return batch; | |
74 } | |
75 | |
76 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which | |
77 // is used to seed the batch with its initial geometry. After seeding, the client should call | |
78 // init() so the Batch can initialize itself | |
79 Geometry& geometry() { return fGeoData[0]; } | |
80 | |
81 void init() { | |
82 const Geometry& geo = fGeoData[0]; | |
83 fBatch.fColor = geo.fColor; | |
84 fBatch.fViewMatrix = geo.fBlob->fViewMatrix; | |
85 | |
86 // We don't yet position distance field text on the cpu, so we have to m ap the vertex bounds | |
87 // into device space | |
88 const Run& run = geo.fBlob->fRuns[geo.fRun]; | |
89 if (run.fSubRunInfo[geo.fSubRun].fDrawAsDistanceFields) { | |
90 SkRect bounds = run.fVertexBounds; | |
91 fBatch.fViewMatrix.mapRect(&bounds); | |
92 this->setBounds(bounds); | |
93 } else { | |
94 this->setBounds(run.fVertexBounds); | |
95 } | |
96 } | |
97 | |
98 const char* name() const override { return "TextBatch"; } | |
99 | |
100 void getInvariantOutputColor(GrInitInvariantOutput* out) const override; | |
101 | |
102 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override; | |
103 | |
104 static size_t GetVertexStride(GrMaskFormat maskFormat) { | |
105 switch (maskFormat) { | |
106 case kA8_GrMaskFormat: | |
107 return kGrayTextVASize; | |
108 case kARGB_GrMaskFormat: | |
109 return kColorTextVASize; | |
110 default: | |
111 return kLCDTextVASize; | |
112 } | |
113 } | |
114 | |
115 static size_t GetVertexStrideDf(GrMaskFormat maskFormat, bool useLCDText) { | |
116 SkASSERT(maskFormat == kA8_GrMaskFormat); | |
117 if (useLCDText) { | |
118 return kLCDTextVASize; | |
119 } else { | |
120 return kGrayTextVASize; | |
121 } | |
122 } | |
123 | |
124 private: | |
125 void initBatchTracker(const GrPipelineOptimizations& opt) override; | |
126 | |
127 struct FlushInfo { | |
128 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer; | |
129 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer; | |
130 int fGlyphsToFlush; | |
131 int fVertexOffset; | |
132 }; | |
133 | |
134 void onPrepareDraws(Target* target) override; | |
135 | |
136 GrAtlasTextBatch() : INHERITED(ClassID()) {} // initialized in factory funct ions. | |
137 | |
138 ~GrAtlasTextBatch() { | |
139 for (int i = 0; i < fGeoCount; i++) { | |
140 fGeoData[i].fBlob->unref(); | |
141 } | |
142 } | |
143 | |
144 GrMaskFormat maskFormat() const { | |
145 switch (fMaskType) { | |
146 case kLCDCoverageMask_MaskType: | |
147 return kA565_GrMaskFormat; | |
148 case kColorBitmapMask_MaskType: | |
149 return kARGB_GrMaskFormat; | |
150 case kGrayscaleCoverageMask_MaskType: | |
151 case kGrayscaleDistanceField_MaskType: | |
152 case kLCDDistanceField_MaskType: | |
153 return kA8_GrMaskFormat; | |
154 } | |
155 return kA8_GrMaskFormat; // suppress warning | |
156 } | |
157 | |
158 bool usesDistanceFields() const { | |
159 return kGrayscaleDistanceField_MaskType == fMaskType || | |
160 kLCDDistanceField_MaskType == fMaskType; | |
161 } | |
162 | |
163 bool isLCD() const { | |
164 return kLCDCoverageMask_MaskType == fMaskType || | |
165 kLCDDistanceField_MaskType == fMaskType; | |
166 } | |
167 | |
168 inline void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexStride); | |
169 | |
170 inline void regenerateColors(intptr_t vertex, size_t vertexStride, GrColor c olor); | |
171 | |
172 inline void regeneratePositions(intptr_t vertex, size_t vertexStride, SkScal ar transX, | |
173 SkScalar transY); | |
174 | |
175 inline void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo); | |
176 | |
177 GrColor color() const { return fBatch.fColor; } | |
178 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | |
179 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | |
180 int numGlyphs() const { return fBatch.fNumGlyphs; } | |
181 | |
182 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override; | |
183 | |
184 // TODO just use class params | |
185 // TODO trying to figure out why lcd is so whack | |
186 GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor fi lteredColor, | |
187 GrColor color, GrTexture* texture); | |
188 | |
189 struct BatchTracker { | |
190 GrColor fColor; | |
191 SkMatrix fViewMatrix; | |
192 bool fUsesLocalCoords; | |
193 bool fColorIgnored; | |
194 bool fCoverageIgnored; | |
195 int fNumGlyphs; | |
196 }; | |
197 | |
198 BatchTracker fBatch; | |
199 // The minimum number of Geometry we will try to allocate. | |
200 enum { kMinGeometryAllocated = 4 }; | |
201 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData; | |
202 int fGeoCount; | |
203 | |
204 enum MaskType { | |
205 kGrayscaleCoverageMask_MaskType, | |
206 kLCDCoverageMask_MaskType, | |
207 kColorBitmapMask_MaskType, | |
208 kGrayscaleDistanceField_MaskType, | |
209 kLCDDistanceField_MaskType, | |
210 } fMaskType; | |
211 bool fUseBGR; // fold this into the enum? | |
212 | |
213 GrBatchFontCache* fFontCache; | |
214 | |
215 // Distance field properties | |
216 SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable; | |
217 SkColor fFilteredColor; | |
218 | |
219 typedef GrVertexBatch INHERITED; | |
220 }; | |
OLD | NEW |