blob: 8f20313378c4bc7b1842db4e06e788a65cee3c46 [file] [log] [blame]
joshualitta751c972015-11-20 13:37:32 -08001/*
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 GrAtlasTextBatch_DEFINED
9#define GrAtlasTextBatch_DEFINED
10
11#include "batches/GrVertexBatch.h"
12
joshualitte8042922015-12-11 06:11:21 -080013#include "text/GrAtlasTextContext.h"
14#include "text/GrDistanceFieldAdjustTable.h"
joshualitta751c972015-11-20 13:37:32 -080015
16class GrAtlasTextBatch : public GrVertexBatch {
17public:
18 DEFINE_BATCH_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080019
joshualitt3660d532015-12-07 11:32:50 -080020 static const int kVerticesPerGlyph = GrAtlasTextBlob::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080021 static const int kIndicesPerGlyph = 6;
22
joshualitta751c972015-11-20 13:37:32 -080023 typedef GrAtlasTextBlob Blob;
24 typedef Blob::Run Run;
25 typedef Run::SubRunInfo TextInfo;
26 struct Geometry {
27 Blob* fBlob;
28 int fRun;
29 int fSubRun;
30 GrColor fColor;
31 SkScalar fTransX;
32 SkScalar fTransY;
33 };
34
35 static GrAtlasTextBatch* CreateBitmap(GrMaskFormat maskFormat, int glyphCount,
36 GrBatchFontCache* fontCache) {
37 GrAtlasTextBatch* batch = new GrAtlasTextBatch;
38
39 batch->fFontCache = fontCache;
40 switch (maskFormat) {
41 case kA8_GrMaskFormat:
42 batch->fMaskType = kGrayscaleCoverageMask_MaskType;
43 break;
44 case kA565_GrMaskFormat:
45 batch->fMaskType = kLCDCoverageMask_MaskType;
46 break;
47 case kARGB_GrMaskFormat:
48 batch->fMaskType = kColorBitmapMask_MaskType;
49 break;
50 }
51 batch->fBatch.fNumGlyphs = glyphCount;
52 batch->fGeoCount = 1;
53 batch->fFilteredColor = 0;
54 batch->fFontCache = fontCache;
55 batch->fUseBGR = false;
56 return batch;
57 }
58
joshualitt1acabf32015-12-10 09:10:10 -080059 static GrAtlasTextBatch* CreateDistanceField(
60 int glyphCount, GrBatchFontCache* fontCache,
61 const GrDistanceFieldAdjustTable* distanceAdjustTable,
62 SkColor filteredColor, bool isLCD,
63 bool useBGR) {
joshualitta751c972015-11-20 13:37:32 -080064 GrAtlasTextBatch* batch = new GrAtlasTextBatch;
65
66 batch->fFontCache = fontCache;
67 batch->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistanceField_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 first 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 map the vertex bounds
joshualitt269a82f2016-01-20 13:54:28 -080087 // into device space
joshualitta751c972015-11-20 13:37:32 -080088 const Run& run = geo.fBlob->fRuns[geo.fRun];
joshualitt3660d532015-12-07 11:32:50 -080089 if (run.fSubRunInfo[geo.fSubRun].drawAsDistanceFields()) {
joshualitt269a82f2016-01-20 13:54:28 -080090 SkRect bounds = run.fVertexBounds;
joshualitta751c972015-11-20 13:37:32 -080091 fBatch.fViewMatrix.mapRect(&bounds);
92 this->setBounds(bounds);
93 } else {
joshualitt269a82f2016-01-20 13:54:28 -080094 this->setBounds(run.fVertexBounds);
joshualitta751c972015-11-20 13:37:32 -080095 }
96 }
97
98 const char* name() const override { return "TextBatch"; }
99
100 SkString dumpInfo() const override;
101
ethannicholasff210322015-11-24 12:10:10 -0800102protected:
103 void computePipelineOptimizations(GrInitInvariantOutput* color,
104 GrInitInvariantOutput* coverage,
105 GrBatchToXPOverrides* overrides) const override;
106
107
joshualitta751c972015-11-20 13:37:32 -0800108private:
ethannicholasff210322015-11-24 12:10:10 -0800109 void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
joshualitta751c972015-11-20 13:37:32 -0800110
111 struct FlushInfo {
112 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
113 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
114 int fGlyphsToFlush;
115 int fVertexOffset;
116 };
117
joshualitt144c3c82015-11-30 12:30:13 -0800118 void onPrepareDraws(Target* target) const override;
joshualitta751c972015-11-20 13:37:32 -0800119
120 GrAtlasTextBatch() : INHERITED(ClassID()) {} // initialized in factory functions.
121
122 ~GrAtlasTextBatch() {
123 for (int i = 0; i < fGeoCount; i++) {
124 fGeoData[i].fBlob->unref();
125 }
126 }
127
128 GrMaskFormat maskFormat() const {
129 switch (fMaskType) {
130 case kLCDCoverageMask_MaskType:
131 return kA565_GrMaskFormat;
132 case kColorBitmapMask_MaskType:
133 return kARGB_GrMaskFormat;
134 case kGrayscaleCoverageMask_MaskType:
135 case kGrayscaleDistanceField_MaskType:
136 case kLCDDistanceField_MaskType:
137 return kA8_GrMaskFormat;
138 }
139 return kA8_GrMaskFormat; // suppress warning
140 }
141
142 bool usesDistanceFields() const {
143 return kGrayscaleDistanceField_MaskType == fMaskType ||
144 kLCDDistanceField_MaskType == fMaskType;
145 }
146
147 bool isLCD() const {
148 return kLCDCoverageMask_MaskType == fMaskType ||
149 kLCDDistanceField_MaskType == fMaskType;
150 }
151
joshualitt60ce86d2015-11-23 13:08:22 -0800152 template <bool regenTexCoords, bool regenPos, bool regenCol, bool regenGlyphs>
153 inline void regenBlob(Target* target, FlushInfo* flushInfo, Blob* blob, Run* run,
154 TextInfo* info, SkGlyphCache** cache,
155 SkTypeface** typeface, GrFontScaler** scaler, const SkDescriptor** desc,
156 const GrGeometryProcessor* gp, int glyphCount, size_t vertexStride,
joshualitt144c3c82015-11-30 12:30:13 -0800157 GrColor color, SkScalar transX, SkScalar transY) const;
joshualitta751c972015-11-20 13:37:32 -0800158
joshualitt144c3c82015-11-30 12:30:13 -0800159 inline void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800160
161 GrColor color() const { return fBatch.fColor; }
162 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
163 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
164 int numGlyphs() const { return fBatch.fNumGlyphs; }
165
166 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
167
168 // TODO just use class params
169 // TODO trying to figure out why lcd is so whack
170 GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor filteredColor,
joshualitt144c3c82015-11-30 12:30:13 -0800171 GrColor color, GrTexture* texture) const;
joshualitta751c972015-11-20 13:37:32 -0800172
173 struct BatchTracker {
174 GrColor fColor;
175 SkMatrix fViewMatrix;
176 bool fUsesLocalCoords;
177 bool fColorIgnored;
178 bool fCoverageIgnored;
179 int fNumGlyphs;
180 };
181
182 BatchTracker fBatch;
183 // The minimum number of Geometry we will try to allocate.
184 enum { kMinGeometryAllocated = 4 };
185 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
186 int fGeoCount;
187
188 enum MaskType {
189 kGrayscaleCoverageMask_MaskType,
190 kLCDCoverageMask_MaskType,
191 kColorBitmapMask_MaskType,
192 kGrayscaleDistanceField_MaskType,
193 kLCDDistanceField_MaskType,
194 } fMaskType;
195 bool fUseBGR; // fold this into the enum?
196
197 GrBatchFontCache* fFontCache;
198
199 // Distance field properties
joshualitt1acabf32015-12-10 09:10:10 -0800200 SkAutoTUnref<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
joshualitta751c972015-11-20 13:37:32 -0800201 SkColor fFilteredColor;
202
203 typedef GrVertexBatch INHERITED;
204};
205
206#endif