blob: d31a3297ecafae77525afbe8ed70e0107b157645 [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"
joshualitte8042922015-12-11 06:11:21 -080012#include "text/GrAtlasTextContext.h"
13#include "text/GrDistanceFieldAdjustTable.h"
joshualitta751c972015-11-20 13:37:32 -080014
Brian Salomoncbcb0a12017-11-19 13:20:13 -050015class SkAtlasTextTarget;
16
Brian Salomon44acb5b2017-07-18 19:59:24 -040017class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080018public:
Brian Salomon25a88092016-12-01 09:36:50 -050019 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080020
Brian Salomonf8334782017-01-03 09:42:58 -050021 ~GrAtlasTextOp() override {
22 for (int i = 0; i < fGeoCount; i++) {
23 fGeoData[i].fBlob->unref();
24 }
25 }
26
joshualitt3660d532015-12-07 11:32:50 -080027 static const int kVerticesPerGlyph = GrAtlasTextBlob::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080028 static const int kIndicesPerGlyph = 6;
29
joshualitta751c972015-11-20 13:37:32 -080030 typedef GrAtlasTextBlob Blob;
joshualitta751c972015-11-20 13:37:32 -080031 struct Geometry {
joshualitt8e0ef292016-02-19 14:13:03 -080032 SkMatrix fViewMatrix;
Jim Van Verth58c3cce2017-10-19 15:50:24 -040033 SkIRect fClipRect;
34 Blob* fBlob;
joshualitt8e0ef292016-02-19 14:13:03 -080035 SkScalar fX;
36 SkScalar fY;
Jim Van Verth56c37142017-10-31 14:44:25 -040037 uint16_t fRun;
38 uint16_t fSubRun;
Jim Van Verth58c3cce2017-10-19 15:50:24 -040039 GrColor fColor;
joshualitta751c972015-11-20 13:37:32 -080040 };
41
Brian Salomon44acb5b2017-07-18 19:59:24 -040042 static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrPaint&& paint, GrMaskFormat maskFormat,
43 int glyphCount, GrAtlasGlyphCache* fontCache) {
44 std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
joshualitta751c972015-11-20 13:37:32 -080045
Brian Salomon344ec422016-12-15 10:58:41 -050046 op->fFontCache = fontCache;
joshualitta751c972015-11-20 13:37:32 -080047 switch (maskFormat) {
48 case kA8_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050049 op->fMaskType = kGrayscaleCoverageMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080050 break;
51 case kA565_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050052 op->fMaskType = kLCDCoverageMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080053 break;
54 case kARGB_GrMaskFormat:
Brian Salomon344ec422016-12-15 10:58:41 -050055 op->fMaskType = kColorBitmapMask_MaskType;
joshualitta751c972015-11-20 13:37:32 -080056 break;
57 }
Brian Salomon344ec422016-12-15 10:58:41 -050058 op->fNumGlyphs = glyphCount;
59 op->fGeoCount = 1;
Jim Van Verthbc2cdd12017-06-08 11:14:35 -040060 op->fLuminanceColor = 0;
Brian Salomon344ec422016-12-15 10:58:41 -050061 op->fFontCache = fontCache;
Brian Salomon344ec422016-12-15 10:58:41 -050062 return op;
joshualitta751c972015-11-20 13:37:32 -080063 }
64
Brian Salomonf8334782017-01-03 09:42:58 -050065 static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
Brian Salomon44acb5b2017-07-18 19:59:24 -040066 GrPaint&& paint, int glyphCount, GrAtlasGlyphCache* fontCache,
Brian Salomon344ec422016-12-15 10:58:41 -050067 const GrDistanceFieldAdjustTable* distanceAdjustTable,
Jim Van Verth90e89b32017-07-06 16:36:55 -040068 bool useGammaCorrectDistanceTable, SkColor luminanceColor, bool isLCD, bool useBGR,
69 bool isAntiAliased) {
Brian Salomon44acb5b2017-07-18 19:59:24 -040070 std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
joshualitta751c972015-11-20 13:37:32 -080071
Brian Salomon344ec422016-12-15 10:58:41 -050072 op->fFontCache = fontCache;
Jim Van Verth90e89b32017-07-06 16:36:55 -040073 op->fMaskType = !isAntiAliased ? kAliasedDistanceField_MaskType
74 : isLCD ? (useBGR ? kLCDBGRDistanceField_MaskType
75 : kLCDDistanceField_MaskType)
76 : kGrayscaleDistanceField_MaskType;
Brian Salomon344ec422016-12-15 10:58:41 -050077 op->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable));
78 op->fUseGammaCorrectDistanceTable = useGammaCorrectDistanceTable;
Jim Van Verthbc2cdd12017-06-08 11:14:35 -040079 op->fLuminanceColor = luminanceColor;
Brian Salomon344ec422016-12-15 10:58:41 -050080 op->fNumGlyphs = glyphCount;
81 op->fGeoCount = 1;
82 return op;
joshualitta751c972015-11-20 13:37:32 -080083 }
84
Brian Salomon344ec422016-12-15 10:58:41 -050085 // To avoid even the initial copy of the struct, we have a getter for the first item which
86 // is used to seed the op with its initial geometry. After seeding, the client should call
87 // init() so the op can initialize itself
joshualitta751c972015-11-20 13:37:32 -080088 Geometry& geometry() { return fGeoData[0]; }
89
90 void init() {
91 const Geometry& geo = fGeoData[0];
Brian Salomon344ec422016-12-15 10:58:41 -050092 fColor = geo.fColor;
bsalomon88cf17d2016-07-08 06:40:56 -070093 SkRect bounds;
94 geo.fBlob->computeSubRunBounds(&bounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX,
joshualitt8e0ef292016-02-19 14:13:03 -080095 geo.fY);
bsalomon88cf17d2016-07-08 06:40:56 -070096 // We don't have tight bounds on the glyph paths in device space. For the purposes of bounds
97 // we treat this as a set of non-AA rects rendered with a texture.
98 this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
joshualitta751c972015-11-20 13:37:32 -080099 }
100
Brian Salomon344ec422016-12-15 10:58:41 -0500101 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -0800102
Robert Phillipsf1748f52017-09-14 14:11:24 -0400103 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400104 fProcessors.visitProxies(func);
105
106 const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(this->maskFormat());
107 for (int i = 0; i < kMaxTextures; ++i) {
108 if (proxies[i]) {
109 func(proxies[i].get());
110 }
111 }
112 }
113
joshualitta751c972015-11-20 13:37:32 -0800114 SkString dumpInfo() const override;
115
Brian Salomon44acb5b2017-07-18 19:59:24 -0400116 FixedFunctionFlags fixedFunctionFlags() const override;
117
Brian Osman9a725dd2017-09-20 09:53:22 -0400118 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
119 GrPixelConfigIsClamped dstIsClamped) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400120
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500121 enum MaskType {
122 kGrayscaleCoverageMask_MaskType,
123 kLCDCoverageMask_MaskType,
124 kColorBitmapMask_MaskType,
125 kAliasedDistanceField_MaskType,
126 kGrayscaleDistanceField_MaskType,
127 kLCDDistanceField_MaskType,
128 kLCDBGRDistanceField_MaskType,
129 };
130
131 MaskType maskType() const { return fMaskType; }
132
Brian Salomon778a2c92017-11-27 12:18:04 -0500133 void finalizeForTextTarget(uint32_t color, const GrCaps&);
134 void executeForTextTarget(SkAtlasTextTarget*);
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500135
joshualitta751c972015-11-20 13:37:32 -0800136private:
Jim Van Verthc8a65e32017-10-25 14:25:27 -0400137 // The minimum number of Geometry we will try to allocate.
Jim Van Verth56c37142017-10-31 14:44:25 -0400138 static constexpr auto kMinGeometryAllocated = 12;
Jim Van Verthc8a65e32017-10-25 14:25:27 -0400139
Brian Salomon44acb5b2017-07-18 19:59:24 -0400140 GrAtlasTextOp(GrPaint&& paint)
141 : INHERITED(ClassID())
Jim Van Verthc8a65e32017-10-25 14:25:27 -0400142 , fGeoDataAllocSize(kMinGeometryAllocated)
Brian Salomon44acb5b2017-07-18 19:59:24 -0400143 , fColor(paint.getColor())
144 , fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
145 , fProcessors(std::move(paint)) {}
joshualitta751c972015-11-20 13:37:32 -0800146
147 struct FlushInfo {
Brian Salomon344ec422016-12-15 10:58:41 -0500148 sk_sp<const GrBuffer> fVertexBuffer;
149 sk_sp<const GrBuffer> fIndexBuffer;
Hal Canary144caf52016-11-07 17:57:18 -0500150 sk_sp<GrGeometryProcessor> fGeometryProcessor;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400151 const GrPipeline* fPipeline;
Brian Salomon344ec422016-12-15 10:58:41 -0500152 int fGlyphsToFlush;
153 int fVertexOffset;
joshualitta751c972015-11-20 13:37:32 -0800154 };
155
Brian Salomon91326c32017-08-09 16:02:19 -0400156 void onPrepareDraws(Target*) override;
joshualitta751c972015-11-20 13:37:32 -0800157
joshualitta751c972015-11-20 13:37:32 -0800158 GrMaskFormat maskFormat() const {
159 switch (fMaskType) {
160 case kLCDCoverageMask_MaskType:
161 return kA565_GrMaskFormat;
162 case kColorBitmapMask_MaskType:
163 return kARGB_GrMaskFormat;
164 case kGrayscaleCoverageMask_MaskType:
Jim Van Verth90e89b32017-07-06 16:36:55 -0400165 case kAliasedDistanceField_MaskType:
joshualitta751c972015-11-20 13:37:32 -0800166 case kGrayscaleDistanceField_MaskType:
167 case kLCDDistanceField_MaskType:
Jim Van Verth90e89b32017-07-06 16:36:55 -0400168 case kLCDBGRDistanceField_MaskType:
joshualitta751c972015-11-20 13:37:32 -0800169 return kA8_GrMaskFormat;
170 }
Brian Salomon344ec422016-12-15 10:58:41 -0500171 return kA8_GrMaskFormat; // suppress warning
joshualitta751c972015-11-20 13:37:32 -0800172 }
173
174 bool usesDistanceFields() const {
Jim Van Verth90e89b32017-07-06 16:36:55 -0400175 return kAliasedDistanceField_MaskType == fMaskType ||
176 kGrayscaleDistanceField_MaskType == fMaskType ||
177 kLCDDistanceField_MaskType == fMaskType ||
178 kLCDBGRDistanceField_MaskType == fMaskType;
joshualitta751c972015-11-20 13:37:32 -0800179 }
180
181 bool isLCD() const {
Jim Van Verth90e89b32017-07-06 16:36:55 -0400182 return kLCDCoverageMask_MaskType == fMaskType ||
183 kLCDDistanceField_MaskType == fMaskType ||
184 kLCDBGRDistanceField_MaskType == fMaskType;
joshualitta751c972015-11-20 13:37:32 -0800185 }
186
Brian Salomone5b399e2017-07-19 13:50:54 -0400187 inline void flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800188
Brian Salomon344ec422016-12-15 10:58:41 -0500189 GrColor color() const { return fColor; }
joshualitt8e0ef292016-02-19 14:13:03 -0800190 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
Brian Salomon344ec422016-12-15 10:58:41 -0500191 bool usesLocalCoords() const { return fUsesLocalCoords; }
192 int numGlyphs() const { return fNumGlyphs; }
joshualitta751c972015-11-20 13:37:32 -0800193
Brian Salomon25a88092016-12-01 09:36:50 -0500194 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800195
Jim Van Vertha950b632017-09-12 11:54:11 -0400196 static constexpr auto kMaxTextures = 4;
Ben Wagner63fd7602017-10-09 15:45:33 -0400197
Jim Van Verth58c3cce2017-10-19 15:50:24 -0400198 sk_sp<GrGeometryProcessor> setupDfProcessor() const;
joshualitta751c972015-11-20 13:37:32 -0800199
Brian Salomon44acb5b2017-07-18 19:59:24 -0400200 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
Jim Van Verthc8a65e32017-10-25 14:25:27 -0400201 int fGeoDataAllocSize;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400202 GrColor fColor;
203 uint32_t fSRGBFlags;
204 GrProcessorSet fProcessors;
205 bool fUsesLocalCoords;
206 bool fCanCombineOnTouchOrOverlap;
207 int fGeoCount;
208 int fNumGlyphs;
209 MaskType fMaskType;
Brian Salomonf856fd12016-12-16 14:24:34 -0500210 GrAtlasGlyphCache* fFontCache;
joshualitta751c972015-11-20 13:37:32 -0800211 // Distance field properties
Hal Canary144caf52016-11-07 17:57:18 -0500212 sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
Jim Van Verthbc2cdd12017-06-08 11:14:35 -0400213 SkColor fLuminanceColor;
brianosmanb461d342016-04-13 13:10:14 -0700214 bool fUseGammaCorrectDistanceTable;
joshualitta751c972015-11-20 13:37:32 -0800215
Brian Salomon44acb5b2017-07-18 19:59:24 -0400216 typedef GrMeshDrawOp INHERITED;
joshualitta751c972015-11-20 13:37:32 -0800217};
218
joshualitta751c972015-11-20 13:37:32 -0800219#endif