blob: ef724770c1d17e642b1406d485c38d83663eb865 [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
Brian Salomon344ec422016-12-15 10:58:41 -05008#ifndef GrAtlasTextOp_DEFINED
9#define GrAtlasTextOp_DEFINED
joshualitta751c972015-11-20 13:37:32 -080010
Brian Salomon89527432016-12-16 09:52:16 -050011#include "ops/GrMeshDrawOp.h"
joshualitta751c972015-11-20 13:37:32 -080012
joshualitte8042922015-12-11 06:11:21 -080013#include "text/GrAtlasTextContext.h"
14#include "text/GrDistanceFieldAdjustTable.h"
joshualitta751c972015-11-20 13:37:32 -080015
Brian Salomon344ec422016-12-15 10:58:41 -050016class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080017public:
Brian Salomon25a88092016-12-01 09:36:50 -050018 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080019
Brian Salomonf8334782017-01-03 09:42:58 -050020 ~GrAtlasTextOp() override {
21 for (int i = 0; i < fGeoCount; i++) {
22 fGeoData[i].fBlob->unref();
23 }
24 }
25
joshualitt3660d532015-12-07 11:32:50 -080026 static const int kVerticesPerGlyph = GrAtlasTextBlob::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080027 static const int kIndicesPerGlyph = 6;
28
joshualitta751c972015-11-20 13:37:32 -080029 typedef GrAtlasTextBlob Blob;
joshualitta751c972015-11-20 13:37:32 -080030 struct Geometry {
joshualitt8e0ef292016-02-19 14:13:03 -080031 SkMatrix fViewMatrix;
joshualitta751c972015-11-20 13:37:32 -080032 Blob* fBlob;
joshualitt8e0ef292016-02-19 14:13:03 -080033 SkScalar fX;
34 SkScalar fY;
joshualitta751c972015-11-20 13:37:32 -080035 int fRun;
36 int fSubRun;
37 GrColor fColor;
joshualitta751c972015-11-20 13:37:32 -080038 };
39
Brian Salomonf8334782017-01-03 09:42:58 -050040 static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrMaskFormat maskFormat, int glyphCount,
41 GrAtlasGlyphCache* fontCache) {
42 std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp);
joshualitta751c972015-11-20 13:37:32 -080043
Brian Salomon344ec422016-12-15 10:58:41 -050044 op->fFontCache = fontCache;
joshualitta751c972015-11-20 13:37:32 -080045 switch (maskFormat) {
46 case kA8_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050047 op->fMaskType = kGrayscaleCoverageMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080048 break;
49 case kA565_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050050 op->fMaskType = kLCDCoverageMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080051 break;
52 case kARGB_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050053 op->fMaskType = kColorBitmapMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080054 break;
55 }
Brian Salomon344ec422016-12-15 10:58:41 -050056 op->fNumGlyphs = glyphCount;
57 op->fGeoCount = 1;
58 op->fFilteredColor = 0;
59 op->fFontCache = fontCache;
60 op->fUseBGR = false;
61 return op;
joshualitta751c972015-11-20 13:37:32 -080062 }
63
Brian Salomonf8334782017-01-03 09:42:58 -050064 static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
Brian Salomonf856fd12016-12-16 14:24:34 -050065 int glyphCount, GrAtlasGlyphCache* fontCache,
Brian Salomon344ec422016-12-15 10:58:41 -050066 const GrDistanceFieldAdjustTable* distanceAdjustTable,
67 bool useGammaCorrectDistanceTable, SkColor filteredColor, bool isLCD, bool useBGR) {
Brian Salomonf8334782017-01-03 09:42:58 -050068 std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp);
joshualitta751c972015-11-20 13:37:32 -080069
Brian Salomon344ec422016-12-15 10:58:41 -050070 op->fFontCache = fontCache;
71 op->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistanceField_MaskType;
72 op->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable));
73 op->fUseGammaCorrectDistanceTable = useGammaCorrectDistanceTable;
74 op->fFilteredColor = filteredColor;
75 op->fUseBGR = useBGR;
76 op->fNumGlyphs = glyphCount;
77 op->fGeoCount = 1;
78 return op;
joshualitta751c972015-11-20 13:37:32 -080079 }
80
Brian Salomon344ec422016-12-15 10:58:41 -050081 // To avoid even the initial copy of the struct, we have a getter for the first item which
82 // is used to seed the op with its initial geometry. After seeding, the client should call
83 // init() so the op can initialize itself
joshualitta751c972015-11-20 13:37:32 -080084 Geometry& geometry() { return fGeoData[0]; }
85
86 void init() {
87 const Geometry& geo = fGeoData[0];
Brian Salomon344ec422016-12-15 10:58:41 -050088 fColor = geo.fColor;
bsalomon88cf17d2016-07-08 06:40:56 -070089 SkRect bounds;
90 geo.fBlob->computeSubRunBounds(&bounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX,
joshualitt8e0ef292016-02-19 14:13:03 -080091 geo.fY);
bsalomon88cf17d2016-07-08 06:40:56 -070092 // We don't have tight bounds on the glyph paths in device space. For the purposes of bounds
93 // we treat this as a set of non-AA rects rendered with a texture.
94 this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
joshualitta751c972015-11-20 13:37:32 -080095 }
96
Brian Salomon344ec422016-12-15 10:58:41 -050097 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080098
99 SkString dumpInfo() const override;
100
joshualitta751c972015-11-20 13:37:32 -0800101private:
Brian Salomon92aee3d2016-12-21 09:20:25 -0500102 void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput*) const override;
103 void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
joshualitta751c972015-11-20 13:37:32 -0800104
105 struct FlushInfo {
Brian Salomon344ec422016-12-15 10:58:41 -0500106 sk_sp<const GrBuffer> fVertexBuffer;
107 sk_sp<const GrBuffer> fIndexBuffer;
Hal Canary144caf52016-11-07 17:57:18 -0500108 sk_sp<GrGeometryProcessor> fGeometryProcessor;
Brian Salomon344ec422016-12-15 10:58:41 -0500109 int fGlyphsToFlush;
110 int fVertexOffset;
joshualitta751c972015-11-20 13:37:32 -0800111 };
112
joshualitt144c3c82015-11-30 12:30:13 -0800113 void onPrepareDraws(Target* target) const override;
joshualitta751c972015-11-20 13:37:32 -0800114
Brian Salomon344ec422016-12-15 10:58:41 -0500115 GrAtlasTextOp() : INHERITED(ClassID()) {} // initialized in factory functions.
joshualitta751c972015-11-20 13:37:32 -0800116
joshualitta751c972015-11-20 13:37:32 -0800117 GrMaskFormat maskFormat() const {
118 switch (fMaskType) {
119 case kLCDCoverageMask_MaskType:
120 return kA565_GrMaskFormat;
121 case kColorBitmapMask_MaskType:
122 return kARGB_GrMaskFormat;
123 case kGrayscaleCoverageMask_MaskType:
124 case kGrayscaleDistanceField_MaskType:
125 case kLCDDistanceField_MaskType:
126 return kA8_GrMaskFormat;
127 }
Brian Salomon344ec422016-12-15 10:58:41 -0500128 return kA8_GrMaskFormat; // suppress warning
joshualitta751c972015-11-20 13:37:32 -0800129 }
130
131 bool usesDistanceFields() const {
132 return kGrayscaleDistanceField_MaskType == fMaskType ||
133 kLCDDistanceField_MaskType == fMaskType;
134 }
135
136 bool isLCD() const {
Brian Salomon344ec422016-12-15 10:58:41 -0500137 return kLCDCoverageMask_MaskType == fMaskType || kLCDDistanceField_MaskType == fMaskType;
joshualitta751c972015-11-20 13:37:32 -0800138 }
139
Brian Salomondad29232016-12-01 16:40:24 -0500140 inline void flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800141
Brian Salomon344ec422016-12-15 10:58:41 -0500142 GrColor color() const { return fColor; }
joshualitt8e0ef292016-02-19 14:13:03 -0800143 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
Brian Salomon344ec422016-12-15 10:58:41 -0500144 bool usesLocalCoords() const { return fUsesLocalCoords; }
145 int numGlyphs() const { return fNumGlyphs; }
joshualitta751c972015-11-20 13:37:32 -0800146
Brian Salomon25a88092016-12-01 09:36:50 -0500147 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800148
149 // TODO just use class params
150 // TODO trying to figure out why lcd is so whack
bungeman06ca8ec2016-06-09 08:01:03 -0700151 sk_sp<GrGeometryProcessor> setupDfProcessor(const SkMatrix& viewMatrix, SkColor filteredColor,
152 GrColor color, GrTexture* texture) const;
joshualitta751c972015-11-20 13:37:32 -0800153
Brian Salomon344ec422016-12-15 10:58:41 -0500154 GrColor fColor;
155 bool fUsesLocalCoords;
156 bool fColorIgnored;
157 bool fCoverageIgnored;
158 int fNumGlyphs;
joshualitta751c972015-11-20 13:37:32 -0800159
joshualitta751c972015-11-20 13:37:32 -0800160 // The minimum number of Geometry we will try to allocate.
161 enum { kMinGeometryAllocated = 4 };
162 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
163 int fGeoCount;
164
165 enum MaskType {
166 kGrayscaleCoverageMask_MaskType,
167 kLCDCoverageMask_MaskType,
168 kColorBitmapMask_MaskType,
169 kGrayscaleDistanceField_MaskType,
170 kLCDDistanceField_MaskType,
171 } fMaskType;
Brian Salomon344ec422016-12-15 10:58:41 -0500172 bool fUseBGR; // fold this into the enum?
joshualitta751c972015-11-20 13:37:32 -0800173
Brian Salomonf856fd12016-12-16 14:24:34 -0500174 GrAtlasGlyphCache* fFontCache;
joshualitta751c972015-11-20 13:37:32 -0800175
176 // Distance field properties
Hal Canary144caf52016-11-07 17:57:18 -0500177 sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
joshualitta751c972015-11-20 13:37:32 -0800178 SkColor fFilteredColor;
brianosmanb461d342016-04-13 13:10:14 -0700179 bool fUseGammaCorrectDistanceTable;
joshualitta751c972015-11-20 13:37:32 -0800180
Brian Salomon344ec422016-12-15 10:58:41 -0500181 friend class GrBlobRegenHelper; // Needs to trigger flushes
joshualittddd22d82016-02-16 06:47:52 -0800182
Brian Salomondad29232016-12-01 16:40:24 -0500183 typedef GrMeshDrawOp INHERITED;
joshualitta751c972015-11-20 13:37:32 -0800184};
185
joshualittddd22d82016-02-16 06:47:52 -0800186/*
187 * A simple helper class to abstract the interface GrAtlasTextBlob needs to regenerate itself.
188 * It'd be nicer if this was nested, but we need to forward declare it in GrAtlasTextBlob.h
189 */
190class GrBlobRegenHelper {
191public:
Brian Salomon344ec422016-12-15 10:58:41 -0500192 GrBlobRegenHelper(const GrAtlasTextOp* op, GrMeshDrawOp::Target* target,
193 GrAtlasTextOp::FlushInfo* flushInfo)
194 : fOp(op), fTarget(target), fFlushInfo(flushInfo) {}
joshualittddd22d82016-02-16 06:47:52 -0800195
196 void flush();
197
Brian Salomon344ec422016-12-15 10:58:41 -0500198 void incGlyphCount(int glyphCount = 1) { fFlushInfo->fGlyphsToFlush += glyphCount; }
joshualittddd22d82016-02-16 06:47:52 -0800199
200private:
Brian Salomon344ec422016-12-15 10:58:41 -0500201 const GrAtlasTextOp* fOp;
Brian Salomondad29232016-12-01 16:40:24 -0500202 GrMeshDrawOp::Target* fTarget;
Brian Salomon344ec422016-12-15 10:58:41 -0500203 GrAtlasTextOp::FlushInfo* fFlushInfo;
joshualittddd22d82016-02-16 06:47:52 -0800204};
205
joshualitta751c972015-11-20 13:37:32 -0800206#endif