blob: 29c5a54faa80ffb429f23655ef13bc93e62c0478 [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 {
Michael Ludwig64596c52020-11-05 12:39:13 -050023 for (const auto& g : fGeometries.items()) {
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 Derby64391c42020-05-16 14:32:15 -040044 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040045
Herb Derby43ad7912020-07-20 16:14:19 -040046 const GrAtlasSubRun& fSubRun;
Herb Derbyeeb30ae2021-02-17 11:27:59 -050047 const SkMatrix fDrawMatrix;
48 const SkPoint fDrawOrigin;
49 const SkIRect fClipRect;
50 GrTextBlob* const fBlob; // mutable to make unref call in Op dtor.
Herb Derby1d17e492020-07-21 11:45:04 -040051
Michael Ludwigefc89d22020-11-05 11:43:10 -050052 // Color is updated after processor analysis if it was determined the shader resolves to
53 // a constant color that we then evaluate on the CPU.
54 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050055 SkPMColor4f fColor;
joshualitta751c972015-11-20 13:37:32 -080056 };
57
Brian Salomon344ec422016-12-15 10:58:41 -050058 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080059
Chris Dalton1706cbf2019-05-21 19:35:29 -060060 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040061
Brian Salomon44acb5b2017-07-18 19:59:24 -040062 FixedFunctionFlags fixedFunctionFlags() const override;
63
Chris Dalton6ce447a2019-06-23 18:07:38 -060064 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
65 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040066
Michael Ludwig136d8782020-11-03 11:04:16 -050067 enum class MaskType : uint32_t {
68 kGrayscaleCoverage,
69 kLCDCoverage,
70 kColorBitmap,
71 kAliasedDistanceField,
72 kGrayscaleDistanceField,
73 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -050074 kLCDBGRDistanceField,
75
76 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -050077 };
Michael Ludwigefc89d22020-11-05 11:43:10 -050078 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050079
Herb Derby4598fa12020-06-10 14:54:22 -040080#if GR_TEST_UTILS
Brian Salomoneebe7352020-12-09 16:37:04 -050081 static GrOp::Owner CreateOpTestingOnly(GrSurfaceDrawContext* rtc,
Herb Derbyc76d4092020-10-07 16:46:15 -040082 const SkPaint& skPaint,
83 const SkFont& font,
84 const SkMatrixProvider& mtxProvider,
85 const char* text,
86 int x,
87 int y);
Herb Derby4598fa12020-06-10 14:54:22 -040088#endif
89
joshualitta751c972015-11-20 13:37:32 -080090private:
Herb Derbyc76d4092020-10-07 16:46:15 -040091 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -040092
Herb Derbyeeb30ae2021-02-17 11:27:59 -050093 struct FlushInfo {
94 sk_sp<const GrBuffer> fVertexBuffer;
95 sk_sp<const GrBuffer> fIndexBuffer;
96 GrGeometryProcessor* fGeometryProcessor;
97 const GrSurfaceProxy** fPrimProcProxies;
98 int fGlyphsToFlush = 0;
99 int fVertexOffset = 0;
100 int fNumDraws = 0;
101 };
102
Herb Derby3c873af2020-04-29 15:56:07 -0400103 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -0400104 bool needsTransform,
105 int glyphCount,
106 SkRect deviceRect,
Herb Derby1d17e492020-07-21 11:45:04 -0400107 const Geometry& geo,
108 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400109
110 GrAtlasTextOp(MaskType maskType,
111 bool needsTransform,
112 int glyphCount,
113 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -0400114 SkColor luminanceColor,
115 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -0400116 uint32_t DFGPFlags,
Herb Derby1d17e492020-07-21 11:45:04 -0400117 const Geometry& geo,
118 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800119
Robert Phillips2669a7b2020-03-12 12:07:19 -0400120 GrProgramInfo* programInfo() override {
121 // TODO [PI]: implement
122 return nullptr;
123 }
124
Robert Phillips4133dc42020-03-11 15:55:55 -0400125 void onCreateProgramInfo(const GrCaps*,
126 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500127 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400128 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400129 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500130 GrXferBarrierFlags renderPassXferBarriers,
131 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400132 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
133 // implemented, the GP is modified at flush time based on the number of pages in the
134 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400135 }
136
Robert Phillips2669a7b2020-03-12 12:07:19 -0400137 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500138 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400139 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400140 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500141 GrXferBarrierFlags renderPassXferBarriers,
142 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400143 // TODO [PI]: implement
144 }
145
Brian Salomon91326c32017-08-09 16:02:19 -0400146 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700147 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800148
John Stilesaf366522020-08-13 09:57:34 -0400149#if GR_TEST_UTILS
150 SkString onDumpInfo() const override;
151#endif
152
joshualitta751c972015-11-20 13:37:32 -0800153 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500154 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500155 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800156 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500157 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800158 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500159 case MaskType::kGrayscaleCoverage:
160 case MaskType::kAliasedDistanceField:
161 case MaskType::kGrayscaleDistanceField:
162 case MaskType::kLCDDistanceField:
163 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800164 return kA8_GrMaskFormat;
165 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500166 // SkUNREACHABLE;
167 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800168 }
169
170 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500171 return MaskType::kAliasedDistanceField == this->maskType() ||
172 MaskType::kGrayscaleDistanceField == this->maskType() ||
173 MaskType::kLCDDistanceField == this->maskType() ||
174 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800175 }
176
177 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500178 return MaskType::kLCDCoverage == this->maskType() ||
179 MaskType::kLCDDistanceField == this->maskType() ||
180 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800181 }
182
Herb Derby4513cdd2020-01-31 13:28:49 -0500183 inline void createDrawForGeneratedGlyphs(
184 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800185
Michael Ludwigefc89d22020-11-05 11:43:10 -0500186 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800187
Herb Derbye25c3002020-10-27 15:57:27 -0400188 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800189
Robert Phillips841c9a52020-03-27 12:41:31 -0400190 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
191 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500192 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500193 const GrSurfaceProxyView* views,
194 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800195
Michael Ludwig64596c52020-11-05 12:39:13 -0500196 // The minimum number of Geometry we will try to allocate as ops are merged together.
197 // The atlas text op holds one Geometry inline. When combined with the linear growth policy,
198 // the total number of geometries follows 6, 18, 36, 60, 90 (the deltas are 6*n).
199 static constexpr auto kMinGeometryAllocated = 6;
200
201 GrTBlockList<Geometry> fGeometries{kMinGeometryAllocated,
202 GrBlockAllocator::GrowthPolicy::kLinear};
Michael Ludwigefc89d22020-11-05 11:43:10 -0500203
204 GrProcessorSet fProcessors;
205 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
206
207 // All combinable atlas ops have equal bit field values
208 uint32_t fDFGPFlags : 9; // Distance field properties
209 uint32_t fMaskType : 3; // MaskType
210 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
211 uint32_t fNeedsGlyphTransform : 1;
212 uint32_t fHasPerspective : 1; // True if perspective affects draw
213 uint32_t fUseGammaCorrectDistanceTable : 1;
214 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
215 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
216
217 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
218 // for single-channel distance fields.
219 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800220
John Stiles7571f9e2020-09-02 22:42:33 -0400221 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800222};
223
joshualitta751c972015-11-20 13:37:32 -0800224#endif