blob: e883fa1d9fff27dd93f1f332d9ba4233f74c9968 [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;
joshualitta751c972015-11-20 13:37:32 -080024 struct Geometry {
joshualitt8e0ef292016-02-19 14:13:03 -080025 SkMatrix fViewMatrix;
joshualitta751c972015-11-20 13:37:32 -080026 Blob* fBlob;
joshualitt8e0ef292016-02-19 14:13:03 -080027 SkScalar fX;
28 SkScalar fY;
joshualitta751c972015-11-20 13:37:32 -080029 int fRun;
30 int fSubRun;
31 GrColor fColor;
joshualitta751c972015-11-20 13:37:32 -080032 };
33
34 static GrAtlasTextBatch* CreateBitmap(GrMaskFormat maskFormat, int glyphCount,
35 GrBatchFontCache* fontCache) {
36 GrAtlasTextBatch* batch = new GrAtlasTextBatch;
37
38 batch->fFontCache = fontCache;
39 switch (maskFormat) {
40 case kA8_GrMaskFormat:
41 batch->fMaskType = kGrayscaleCoverageMask_MaskType;
42 break;
43 case kA565_GrMaskFormat:
44 batch->fMaskType = kLCDCoverageMask_MaskType;
45 break;
46 case kARGB_GrMaskFormat:
47 batch->fMaskType = kColorBitmapMask_MaskType;
48 break;
49 }
50 batch->fBatch.fNumGlyphs = glyphCount;
51 batch->fGeoCount = 1;
52 batch->fFilteredColor = 0;
53 batch->fFontCache = fontCache;
54 batch->fUseBGR = false;
55 return batch;
56 }
57
joshualitt1acabf32015-12-10 09:10:10 -080058 static GrAtlasTextBatch* CreateDistanceField(
59 int glyphCount, GrBatchFontCache* fontCache,
60 const GrDistanceFieldAdjustTable* distanceAdjustTable,
61 SkColor filteredColor, bool isLCD,
62 bool useBGR) {
joshualitta751c972015-11-20 13:37:32 -080063 GrAtlasTextBatch* batch = new GrAtlasTextBatch;
64
65 batch->fFontCache = fontCache;
66 batch->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistanceField_MaskType;
67 batch->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable));
68 batch->fFilteredColor = filteredColor;
69 batch->fUseBGR = useBGR;
70 batch->fBatch.fNumGlyphs = glyphCount;
71 batch->fGeoCount = 1;
72 return batch;
73 }
74
75 // to avoid even the initial copy of the struct, we have a getter for the first item which
76 // is used to seed the batch with its initial geometry. After seeding, the client should call
77 // init() so the Batch can initialize itself
78 Geometry& geometry() { return fGeoData[0]; }
79
80 void init() {
81 const Geometry& geo = fGeoData[0];
82 fBatch.fColor = geo.fColor;
joshualitta751c972015-11-20 13:37:32 -080083
joshualitt8e0ef292016-02-19 14:13:03 -080084 geo.fBlob->computeSubRunBounds(&fBounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX,
85 geo.fY);
joshualitta751c972015-11-20 13:37:32 -080086 }
87
88 const char* name() const override { return "TextBatch"; }
89
90 SkString dumpInfo() const override;
91
ethannicholasff210322015-11-24 12:10:10 -080092protected:
halcanary9d524f22016-03-29 09:03:52 -070093 void computePipelineOptimizations(GrInitInvariantOutput* color,
ethannicholasff210322015-11-24 12:10:10 -080094 GrInitInvariantOutput* coverage,
95 GrBatchToXPOverrides* overrides) const override;
96
97
joshualitta751c972015-11-20 13:37:32 -080098private:
ethannicholasff210322015-11-24 12:10:10 -080099 void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
joshualitta751c972015-11-20 13:37:32 -0800100
101 struct FlushInfo {
bsalomon342bfc22016-04-01 06:06:20 -0700102 SkAutoTUnref<const GrBuffer> fVertexBuffer;
103 SkAutoTUnref<const GrBuffer> fIndexBuffer;
104 SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
105 int fGlyphsToFlush;
106 int fVertexOffset;
joshualitta751c972015-11-20 13:37:32 -0800107 };
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
joshualitt144c3c82015-11-30 12:30:13 -0800143 inline void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800144
145 GrColor color() const { return fBatch.fColor; }
joshualitt8e0ef292016-02-19 14:13:03 -0800146 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
joshualitta751c972015-11-20 13:37:32 -0800147 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
148 int numGlyphs() const { return fBatch.fNumGlyphs; }
149
150 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
151
152 // TODO just use class params
153 // TODO trying to figure out why lcd is so whack
154 GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor filteredColor,
joshualitt144c3c82015-11-30 12:30:13 -0800155 GrColor color, GrTexture* texture) const;
joshualitta751c972015-11-20 13:37:32 -0800156
157 struct BatchTracker {
158 GrColor fColor;
joshualitta751c972015-11-20 13:37:32 -0800159 bool fUsesLocalCoords;
160 bool fColorIgnored;
161 bool fCoverageIgnored;
162 int fNumGlyphs;
163 };
164
165 BatchTracker fBatch;
166 // The minimum number of Geometry we will try to allocate.
167 enum { kMinGeometryAllocated = 4 };
168 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
169 int fGeoCount;
170
171 enum MaskType {
172 kGrayscaleCoverageMask_MaskType,
173 kLCDCoverageMask_MaskType,
174 kColorBitmapMask_MaskType,
175 kGrayscaleDistanceField_MaskType,
176 kLCDDistanceField_MaskType,
177 } fMaskType;
178 bool fUseBGR; // fold this into the enum?
179
180 GrBatchFontCache* fFontCache;
181
182 // Distance field properties
joshualitt1acabf32015-12-10 09:10:10 -0800183 SkAutoTUnref<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
joshualitta751c972015-11-20 13:37:32 -0800184 SkColor fFilteredColor;
185
joshualittddd22d82016-02-16 06:47:52 -0800186 friend class GrBlobRegenHelper; // Needs to trigger flushes
187
joshualitta751c972015-11-20 13:37:32 -0800188 typedef GrVertexBatch INHERITED;
189};
190
joshualittddd22d82016-02-16 06:47:52 -0800191/*
192 * A simple helper class to abstract the interface GrAtlasTextBlob needs to regenerate itself.
193 * It'd be nicer if this was nested, but we need to forward declare it in GrAtlasTextBlob.h
194 */
195class GrBlobRegenHelper {
196public:
197 GrBlobRegenHelper(const GrAtlasTextBatch* batch,
198 GrVertexBatch::Target* target,
bsalomon342bfc22016-04-01 06:06:20 -0700199 GrAtlasTextBatch::FlushInfo* flushInfo)
joshualittddd22d82016-02-16 06:47:52 -0800200 : fBatch(batch)
201 , fTarget(target)
bsalomon342bfc22016-04-01 06:06:20 -0700202 , fFlushInfo(flushInfo) {}
joshualittddd22d82016-02-16 06:47:52 -0800203
204 void flush();
205
206 void incGlyphCount(int glyphCount = 1) {
207 fFlushInfo->fGlyphsToFlush += glyphCount;
208 }
209
210private:
211 const GrAtlasTextBatch* fBatch;
212 GrVertexBatch::Target* fTarget;
213 GrAtlasTextBatch::FlushInfo* fFlushInfo;
joshualittddd22d82016-02-16 06:47:52 -0800214};
215
joshualitta751c972015-11-20 13:37:32 -0800216#endif