blob: 7c3e191f7bff771cf3db832922d2db62cf9c15d8 [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
Michael Ludwig64596c52020-11-05 12:39:13 -050011#include "src/gpu/GrTBlockList.h"
Michael Ludwigefc89d22020-11-05 11:43:10 -050012#include "src/gpu/effects/GrDistanceFieldGeoProc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/ops/GrMeshDrawOp.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/text/GrTextBlob.h"
joshualitta751c972015-11-20 13:37:32 -080015
Robert Phillipsb97da532019-02-12 15:24:12 -050016class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050017
Brian Salomon44acb5b2017-07-18 19:59:24 -040018class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080019public:
Brian Salomon25a88092016-12-01 09:36:50 -050020 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080021
Brian Salomonf8334782017-01-03 09:42:58 -050022 ~GrAtlasTextOp() override {
Herb Derby6b748e42020-12-02 17:44:54 -050023 for (const Geometry* g = fHead; g != nullptr; g = g->fNext) {
24 g->fBlob->unref();
Brian Salomonf8334782017-01-03 09:42:58 -050025 }
26 }
27
Herb Derby252a3c02020-07-14 12:15:34 -040028 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080029 static const int kIndicesPerGlyph = 6;
30
joshualitta751c972015-11-20 13:37:32 -080031 struct Geometry {
Herb Derbyeeb30ae2021-02-17 11:27:59 -050032 Geometry(const GrAtlasSubRun& subRun,
33 const SkMatrix& drawMatrix,
34 SkPoint drawOrigin,
35 SkIRect clipRect,
36 GrTextBlob* blob,
37 const SkPMColor4f& color)
38 : fSubRun{subRun}
39 , fDrawMatrix{drawMatrix}
40 , fDrawOrigin{drawOrigin}
41 , fClipRect{clipRect}
42 , fBlob{blob}
43 , fColor{color} {}
Herb Derby6b748e42020-12-02 17:44:54 -050044
45 static Geometry* Make(GrRecordingContext* rc,
46 const GrAtlasSubRun& subRun,
47 const SkMatrix& drawMatrix,
48 SkPoint drawOrigin,
49 SkIRect clipRect,
50 GrTextBlob* blob,
51 const SkPMColor4f& color);
Herb Derby64391c42020-05-16 14:32:15 -040052 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040053
Herb Derby43ad7912020-07-20 16:14:19 -040054 const GrAtlasSubRun& fSubRun;
Herb Derbyeeb30ae2021-02-17 11:27:59 -050055 const SkMatrix fDrawMatrix;
56 const SkPoint fDrawOrigin;
Herb Derby6b748e42020-12-02 17:44:54 -050057 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
58 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050059 const SkIRect fClipRect;
60 GrTextBlob* const fBlob; // mutable to make unref call in Op dtor.
Herb Derby1d17e492020-07-21 11:45:04 -040061
Michael Ludwigefc89d22020-11-05 11:43:10 -050062 // Color is updated after processor analysis if it was determined the shader resolves to
63 // a constant color that we then evaluate on the CPU.
64 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050065 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050066 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080067 };
68
Brian Salomon344ec422016-12-15 10:58:41 -050069 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080070
Chris Dalton1706cbf2019-05-21 19:35:29 -060071 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040072
Brian Salomon44acb5b2017-07-18 19:59:24 -040073 FixedFunctionFlags fixedFunctionFlags() const override;
74
Chris Dalton6ce447a2019-06-23 18:07:38 -060075 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
76 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040077
Michael Ludwig136d8782020-11-03 11:04:16 -050078 enum class MaskType : uint32_t {
79 kGrayscaleCoverage,
80 kLCDCoverage,
81 kColorBitmap,
82 kAliasedDistanceField,
83 kGrayscaleDistanceField,
84 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -050085 kLCDBGRDistanceField,
86
87 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -050088 };
Michael Ludwigefc89d22020-11-05 11:43:10 -050089 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050090
Herb Derby4598fa12020-06-10 14:54:22 -040091#if GR_TEST_UTILS
Brian Salomoneebe7352020-12-09 16:37:04 -050092 static GrOp::Owner CreateOpTestingOnly(GrSurfaceDrawContext* rtc,
Herb Derbyc76d4092020-10-07 16:46:15 -040093 const SkPaint& skPaint,
94 const SkFont& font,
95 const SkMatrixProvider& mtxProvider,
96 const char* text,
97 int x,
98 int y);
Herb Derby4598fa12020-06-10 14:54:22 -040099#endif
100
joshualitta751c972015-11-20 13:37:32 -0800101private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400102 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400103
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500104 struct FlushInfo {
105 sk_sp<const GrBuffer> fVertexBuffer;
106 sk_sp<const GrBuffer> fIndexBuffer;
107 GrGeometryProcessor* fGeometryProcessor;
108 const GrSurfaceProxy** fPrimProcProxies;
109 int fGlyphsToFlush = 0;
110 int fVertexOffset = 0;
111 int fNumDraws = 0;
112 };
113
Herb Derby3c873af2020-04-29 15:56:07 -0400114 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -0400115 bool needsTransform,
116 int glyphCount,
117 SkRect deviceRect,
Herb Derby6b748e42020-12-02 17:44:54 -0500118 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400119 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400120
121 GrAtlasTextOp(MaskType maskType,
122 bool needsTransform,
123 int glyphCount,
124 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -0400125 SkColor luminanceColor,
126 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -0400127 uint32_t DFGPFlags,
Herb Derby6b748e42020-12-02 17:44:54 -0500128 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400129 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800130
Robert Phillips2669a7b2020-03-12 12:07:19 -0400131 GrProgramInfo* programInfo() override {
132 // TODO [PI]: implement
133 return nullptr;
134 }
135
Herb Derby6b748e42020-12-02 17:44:54 -0500136 void addGeometry(Geometry* geometry) {
137 *fTail = geometry;
138 // The geometry may have many entries. Find the end.
139 do {
140 fTail = &(*fTail)->fNext;
141 } while (*fTail != nullptr);
142 }
143
Robert Phillips4133dc42020-03-11 15:55:55 -0400144 void onCreateProgramInfo(const GrCaps*,
145 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500146 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400147 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400148 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500149 GrXferBarrierFlags renderPassXferBarriers,
150 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400151 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
152 // implemented, the GP is modified at flush time based on the number of pages in the
153 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400154 }
155
Robert Phillips2669a7b2020-03-12 12:07:19 -0400156 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500157 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400158 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400159 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500160 GrXferBarrierFlags renderPassXferBarriers,
161 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400162 // TODO [PI]: implement
163 }
164
Brian Salomon91326c32017-08-09 16:02:19 -0400165 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700166 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800167
John Stilesaf366522020-08-13 09:57:34 -0400168#if GR_TEST_UTILS
169 SkString onDumpInfo() const override;
170#endif
171
joshualitta751c972015-11-20 13:37:32 -0800172 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500173 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500174 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800175 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500176 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800177 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500178 case MaskType::kGrayscaleCoverage:
179 case MaskType::kAliasedDistanceField:
180 case MaskType::kGrayscaleDistanceField:
181 case MaskType::kLCDDistanceField:
182 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800183 return kA8_GrMaskFormat;
184 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500185 // SkUNREACHABLE;
186 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800187 }
188
189 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500190 return MaskType::kAliasedDistanceField == this->maskType() ||
191 MaskType::kGrayscaleDistanceField == this->maskType() ||
192 MaskType::kLCDDistanceField == this->maskType() ||
193 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800194 }
195
196 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500197 return MaskType::kLCDCoverage == this->maskType() ||
198 MaskType::kLCDDistanceField == this->maskType() ||
199 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800200 }
201
Herb Derby4513cdd2020-01-31 13:28:49 -0500202 inline void createDrawForGeneratedGlyphs(
203 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800204
Michael Ludwigefc89d22020-11-05 11:43:10 -0500205 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800206
Herb Derbye25c3002020-10-27 15:57:27 -0400207 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800208
Robert Phillips841c9a52020-03-27 12:41:31 -0400209 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
210 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500211 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500212 const GrSurfaceProxyView* views,
213 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800214
Michael Ludwigefc89d22020-11-05 11:43:10 -0500215 GrProcessorSet fProcessors;
216 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
217
218 // All combinable atlas ops have equal bit field values
219 uint32_t fDFGPFlags : 9; // Distance field properties
220 uint32_t fMaskType : 3; // MaskType
221 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
222 uint32_t fNeedsGlyphTransform : 1;
223 uint32_t fHasPerspective : 1; // True if perspective affects draw
224 uint32_t fUseGammaCorrectDistanceTable : 1;
225 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
226 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
227
228 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
229 // for single-channel distance fields.
230 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800231
Herb Derby6b748e42020-12-02 17:44:54 -0500232 Geometry* fHead{nullptr};
233 Geometry** fTail{&fHead};
234
John Stiles7571f9e2020-09-02 22:42:33 -0400235 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800236};
237
joshualitta751c972015-11-20 13:37:32 -0800238#endif