blob: 05d6afdb5184a44eab6affd7c4eed2d68a9e1169 [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;
joshualittbc811112016-02-11 12:42:02 -080084 fBatch.fViewMatrix = geo.fBlob->viewMatrix();
joshualitta751c972015-11-20 13:37:32 -080085
joshualittbc811112016-02-11 12:42:02 -080086 geo.fBlob->computeSubRunBounds(&fBounds, geo.fRun, geo.fSubRun);
joshualitta751c972015-11-20 13:37:32 -080087 }
88
89 const char* name() const override { return "TextBatch"; }
90
91 SkString dumpInfo() const override;
92
ethannicholasff210322015-11-24 12:10:10 -080093protected:
94 void computePipelineOptimizations(GrInitInvariantOutput* color,
95 GrInitInvariantOutput* coverage,
96 GrBatchToXPOverrides* overrides) const override;
97
98
joshualitta751c972015-11-20 13:37:32 -080099private:
ethannicholasff210322015-11-24 12:10:10 -0800100 void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
joshualitta751c972015-11-20 13:37:32 -0800101
102 struct FlushInfo {
103 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
104 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
105 int fGlyphsToFlush;
106 int fVertexOffset;
107 };
108
joshualitt144c3c82015-11-30 12:30:13 -0800109 void onPrepareDraws(Target* target) const override;
joshualitta751c972015-11-20 13:37:32 -0800110
111 GrAtlasTextBatch() : INHERITED(ClassID()) {} // initialized in factory functions.
112
113 ~GrAtlasTextBatch() {
114 for (int i = 0; i < fGeoCount; i++) {
115 fGeoData[i].fBlob->unref();
116 }
117 }
118
119 GrMaskFormat maskFormat() const {
120 switch (fMaskType) {
121 case kLCDCoverageMask_MaskType:
122 return kA565_GrMaskFormat;
123 case kColorBitmapMask_MaskType:
124 return kARGB_GrMaskFormat;
125 case kGrayscaleCoverageMask_MaskType:
126 case kGrayscaleDistanceField_MaskType:
127 case kLCDDistanceField_MaskType:
128 return kA8_GrMaskFormat;
129 }
130 return kA8_GrMaskFormat; // suppress warning
131 }
132
133 bool usesDistanceFields() const {
134 return kGrayscaleDistanceField_MaskType == fMaskType ||
135 kLCDDistanceField_MaskType == fMaskType;
136 }
137
138 bool isLCD() const {
139 return kLCDCoverageMask_MaskType == fMaskType ||
140 kLCDDistanceField_MaskType == fMaskType;
141 }
142
joshualitt60ce86d2015-11-23 13:08:22 -0800143 template <bool regenTexCoords, bool regenPos, bool regenCol, bool regenGlyphs>
144 inline void regenBlob(Target* target, FlushInfo* flushInfo, Blob* blob, Run* run,
145 TextInfo* info, SkGlyphCache** cache,
146 SkTypeface** typeface, GrFontScaler** scaler, const SkDescriptor** desc,
147 const GrGeometryProcessor* gp, int glyphCount, size_t vertexStride,
joshualitt144c3c82015-11-30 12:30:13 -0800148 GrColor color, SkScalar transX, SkScalar transY) const;
joshualitta751c972015-11-20 13:37:32 -0800149
joshualitt144c3c82015-11-30 12:30:13 -0800150 inline void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800151
152 GrColor color() const { return fBatch.fColor; }
153 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
154 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
155 int numGlyphs() const { return fBatch.fNumGlyphs; }
156
157 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
158
159 // TODO just use class params
160 // TODO trying to figure out why lcd is so whack
161 GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor filteredColor,
joshualitt144c3c82015-11-30 12:30:13 -0800162 GrColor color, GrTexture* texture) const;
joshualitta751c972015-11-20 13:37:32 -0800163
164 struct BatchTracker {
165 GrColor fColor;
166 SkMatrix fViewMatrix;
167 bool fUsesLocalCoords;
168 bool fColorIgnored;
169 bool fCoverageIgnored;
170 int fNumGlyphs;
171 };
172
173 BatchTracker fBatch;
174 // The minimum number of Geometry we will try to allocate.
175 enum { kMinGeometryAllocated = 4 };
176 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
177 int fGeoCount;
178
179 enum MaskType {
180 kGrayscaleCoverageMask_MaskType,
181 kLCDCoverageMask_MaskType,
182 kColorBitmapMask_MaskType,
183 kGrayscaleDistanceField_MaskType,
184 kLCDDistanceField_MaskType,
185 } fMaskType;
186 bool fUseBGR; // fold this into the enum?
187
188 GrBatchFontCache* fFontCache;
189
190 // Distance field properties
joshualitt1acabf32015-12-10 09:10:10 -0800191 SkAutoTUnref<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
joshualitta751c972015-11-20 13:37:32 -0800192 SkColor fFilteredColor;
193
194 typedef GrVertexBatch INHERITED;
195};
196
197#endif