blob: ad4733717de4a47c3c021726704008d874a05de3 [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) {
Herb Derby4f78f232021-02-18 10:42:35 -050024 g->~Geometry();
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,
Herb Derby4f78f232021-02-18 10:42:35 -050036 sk_sp<GrTextBlob> blob,
Herb Derbyeeb30ae2021-02-17 11:27:59 -050037 const SkPMColor4f& color)
38 : fSubRun{subRun}
39 , fDrawMatrix{drawMatrix}
40 , fDrawOrigin{drawOrigin}
41 , fClipRect{clipRect}
Herb Derby4f78f232021-02-18 10:42:35 -050042 , fBlob{std::move(blob)}
Herb Derbyeeb30ae2021-02-17 11:27:59 -050043 , 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,
Herb Derby4f78f232021-02-18 10:42:35 -050050 sk_sp<GrTextBlob> blob,
Herb Derby6b748e42020-12-02 17:44:54 -050051 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 Derby4f78f232021-02-18 10:42:35 -050057
Herb Derby6b748e42020-12-02 17:44:54 -050058 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
59 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050060 const SkIRect fClipRect;
Herb Derby4f78f232021-02-18 10:42:35 -050061 sk_sp<GrTextBlob> fBlob; // mutable to make unref call in Op dtor.
Herb Derby1d17e492020-07-21 11:45:04 -040062
Michael Ludwigefc89d22020-11-05 11:43:10 -050063 // Color is updated after processor analysis if it was determined the shader resolves to
64 // a constant color that we then evaluate on the CPU.
65 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050066 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050067 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080068 };
69
Brian Salomon344ec422016-12-15 10:58:41 -050070 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080071
Chris Dalton1706cbf2019-05-21 19:35:29 -060072 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040073
Brian Salomon44acb5b2017-07-18 19:59:24 -040074 FixedFunctionFlags fixedFunctionFlags() const override;
75
Chris Dalton6ce447a2019-06-23 18:07:38 -060076 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
77 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040078
Michael Ludwig136d8782020-11-03 11:04:16 -050079 enum class MaskType : uint32_t {
80 kGrayscaleCoverage,
81 kLCDCoverage,
82 kColorBitmap,
83 kAliasedDistanceField,
84 kGrayscaleDistanceField,
85 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -050086 kLCDBGRDistanceField,
87
88 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -050089 };
Michael Ludwigefc89d22020-11-05 11:43:10 -050090 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050091
Herb Derby4598fa12020-06-10 14:54:22 -040092#if GR_TEST_UTILS
Brian Salomoneebe7352020-12-09 16:37:04 -050093 static GrOp::Owner CreateOpTestingOnly(GrSurfaceDrawContext* rtc,
Herb Derbyc76d4092020-10-07 16:46:15 -040094 const SkPaint& skPaint,
95 const SkFont& font,
96 const SkMatrixProvider& mtxProvider,
97 const char* text,
98 int x,
99 int y);
Herb Derby4598fa12020-06-10 14:54:22 -0400100#endif
101
joshualitta751c972015-11-20 13:37:32 -0800102private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400103 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400104
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500105 struct FlushInfo {
106 sk_sp<const GrBuffer> fVertexBuffer;
107 sk_sp<const GrBuffer> fIndexBuffer;
108 GrGeometryProcessor* fGeometryProcessor;
109 const GrSurfaceProxy** fPrimProcProxies;
110 int fGlyphsToFlush = 0;
111 int fVertexOffset = 0;
112 int fNumDraws = 0;
113 };
114
Herb Derby3c873af2020-04-29 15:56:07 -0400115 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -0400116 bool needsTransform,
117 int glyphCount,
118 SkRect deviceRect,
Herb Derby6b748e42020-12-02 17:44:54 -0500119 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400120 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400121
122 GrAtlasTextOp(MaskType maskType,
123 bool needsTransform,
124 int glyphCount,
125 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -0400126 SkColor luminanceColor,
127 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -0400128 uint32_t DFGPFlags,
Herb Derby6b748e42020-12-02 17:44:54 -0500129 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400130 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800131
Robert Phillips2669a7b2020-03-12 12:07:19 -0400132 GrProgramInfo* programInfo() override {
133 // TODO [PI]: implement
134 return nullptr;
135 }
136
Herb Derby6b748e42020-12-02 17:44:54 -0500137 void addGeometry(Geometry* geometry) {
138 *fTail = geometry;
139 // The geometry may have many entries. Find the end.
140 do {
141 fTail = &(*fTail)->fNext;
142 } while (*fTail != nullptr);
143 }
144
Robert Phillips4133dc42020-03-11 15:55:55 -0400145 void onCreateProgramInfo(const GrCaps*,
146 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500147 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400148 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400149 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500150 GrXferBarrierFlags renderPassXferBarriers,
151 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400152 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
153 // implemented, the GP is modified at flush time based on the number of pages in the
154 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400155 }
156
Robert Phillips2669a7b2020-03-12 12:07:19 -0400157 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500158 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400159 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400160 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500161 GrXferBarrierFlags renderPassXferBarriers,
162 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400163 // TODO [PI]: implement
164 }
165
Brian Salomon91326c32017-08-09 16:02:19 -0400166 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700167 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800168
John Stilesaf366522020-08-13 09:57:34 -0400169#if GR_TEST_UTILS
170 SkString onDumpInfo() const override;
171#endif
172
joshualitta751c972015-11-20 13:37:32 -0800173 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500174 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500175 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800176 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500177 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800178 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500179 case MaskType::kGrayscaleCoverage:
180 case MaskType::kAliasedDistanceField:
181 case MaskType::kGrayscaleDistanceField:
182 case MaskType::kLCDDistanceField:
183 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800184 return kA8_GrMaskFormat;
185 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500186 // SkUNREACHABLE;
187 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800188 }
189
190 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500191 return MaskType::kAliasedDistanceField == this->maskType() ||
192 MaskType::kGrayscaleDistanceField == this->maskType() ||
193 MaskType::kLCDDistanceField == this->maskType() ||
194 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800195 }
196
197 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500198 return MaskType::kLCDCoverage == this->maskType() ||
199 MaskType::kLCDDistanceField == this->maskType() ||
200 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800201 }
202
Herb Derby4513cdd2020-01-31 13:28:49 -0500203 inline void createDrawForGeneratedGlyphs(
204 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800205
Michael Ludwigefc89d22020-11-05 11:43:10 -0500206 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800207
Herb Derbye25c3002020-10-27 15:57:27 -0400208 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800209
Robert Phillips841c9a52020-03-27 12:41:31 -0400210 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
211 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500212 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500213 const GrSurfaceProxyView* views,
214 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800215
Michael Ludwigefc89d22020-11-05 11:43:10 -0500216 GrProcessorSet fProcessors;
217 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
218
219 // All combinable atlas ops have equal bit field values
220 uint32_t fDFGPFlags : 9; // Distance field properties
221 uint32_t fMaskType : 3; // MaskType
222 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
223 uint32_t fNeedsGlyphTransform : 1;
224 uint32_t fHasPerspective : 1; // True if perspective affects draw
225 uint32_t fUseGammaCorrectDistanceTable : 1;
226 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
227 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
228
229 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
230 // for single-channel distance fields.
231 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800232
Herb Derby6b748e42020-12-02 17:44:54 -0500233 Geometry* fHead{nullptr};
234 Geometry** fTail{&fHead};
235
John Stiles7571f9e2020-09-02 22:42:33 -0400236 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800237};
238
joshualitta751c972015-11-20 13:37:32 -0800239#endif