blob: 770adc5fea9e3f68cebb6c730a442b6c8de91ef3 [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
Herb Derby93330c92021-02-26 12:18:26 -050016#if !defined(SK_BUILD_FOR_IOS) || \
17 (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_9_0)
18 #define GR_HAS_THREAD_LOCAL
19#endif
20
Robert Phillipsb97da532019-02-12 15:24:12 -050021class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050022
Brian Salomon44acb5b2017-07-18 19:59:24 -040023class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080024public:
Brian Salomon25a88092016-12-01 09:36:50 -050025 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080026
Brian Salomonf8334782017-01-03 09:42:58 -050027 ~GrAtlasTextOp() override {
Herb Derby6b748e42020-12-02 17:44:54 -050028 for (const Geometry* g = fHead; g != nullptr; g = g->fNext) {
Herb Derby4f78f232021-02-18 10:42:35 -050029 g->~Geometry();
Brian Salomonf8334782017-01-03 09:42:58 -050030 }
31 }
32
Herb Derby32302552021-03-11 18:27:35 -050033#if defined(GR_HAS_THREAD_LOCAL)
Herb Derby93330c92021-02-26 12:18:26 -050034 void* operator new(size_t s);
35 void operator delete(void* b) noexcept;
36 static void ClearCache();
Robert Phillipse44c4842021-03-15 21:27:19 +000037#else
38 static void ClearCache() {}
Herb Derby93330c92021-02-26 12:18:26 -050039#endif
40
Herb Derby252a3c02020-07-14 12:15:34 -040041 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080042 static const int kIndicesPerGlyph = 6;
43
joshualitta751c972015-11-20 13:37:32 -080044 struct Geometry {
Herb Derbyeeb30ae2021-02-17 11:27:59 -050045 Geometry(const GrAtlasSubRun& subRun,
46 const SkMatrix& drawMatrix,
47 SkPoint drawOrigin,
48 SkIRect clipRect,
Herb Derby4f78f232021-02-18 10:42:35 -050049 sk_sp<GrTextBlob> blob,
Herb Derbyeeb30ae2021-02-17 11:27:59 -050050 const SkPMColor4f& color)
51 : fSubRun{subRun}
52 , fDrawMatrix{drawMatrix}
53 , fDrawOrigin{drawOrigin}
54 , fClipRect{clipRect}
Herb Derby4f78f232021-02-18 10:42:35 -050055 , fBlob{std::move(blob)}
Herb Derbyeeb30ae2021-02-17 11:27:59 -050056 , fColor{color} {}
Herb Derby6b748e42020-12-02 17:44:54 -050057
58 static Geometry* Make(GrRecordingContext* rc,
59 const GrAtlasSubRun& subRun,
60 const SkMatrix& drawMatrix,
61 SkPoint drawOrigin,
62 SkIRect clipRect,
Herb Derby4f78f232021-02-18 10:42:35 -050063 sk_sp<GrTextBlob> blob,
Herb Derby6b748e42020-12-02 17:44:54 -050064 const SkPMColor4f& color);
Herb Derby64391c42020-05-16 14:32:15 -040065 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040066
Herb Derby43ad7912020-07-20 16:14:19 -040067 const GrAtlasSubRun& fSubRun;
Herb Derbyeeb30ae2021-02-17 11:27:59 -050068 const SkMatrix fDrawMatrix;
69 const SkPoint fDrawOrigin;
Herb Derby4f78f232021-02-18 10:42:35 -050070
Herb Derby6b748e42020-12-02 17:44:54 -050071 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
72 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050073 const SkIRect fClipRect;
Herb Derby4f78f232021-02-18 10:42:35 -050074 sk_sp<GrTextBlob> fBlob; // mutable to make unref call in Op dtor.
Herb Derby1d17e492020-07-21 11:45:04 -040075
Michael Ludwigefc89d22020-11-05 11:43:10 -050076 // Color is updated after processor analysis if it was determined the shader resolves to
77 // a constant color that we then evaluate on the CPU.
78 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050079 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050080 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080081 };
82
Brian Salomon344ec422016-12-15 10:58:41 -050083 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080084
Chris Dalton1706cbf2019-05-21 19:35:29 -060085 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040086
Brian Salomon44acb5b2017-07-18 19:59:24 -040087 FixedFunctionFlags fixedFunctionFlags() const override;
88
Chris Dalton6ce447a2019-06-23 18:07:38 -060089 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
90 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040091
Michael Ludwig136d8782020-11-03 11:04:16 -050092 enum class MaskType : uint32_t {
93 kGrayscaleCoverage,
94 kLCDCoverage,
95 kColorBitmap,
96 kAliasedDistanceField,
97 kGrayscaleDistanceField,
98 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -050099 kLCDBGRDistanceField,
100
101 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500102 };
Michael Ludwigefc89d22020-11-05 11:43:10 -0500103 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500104
Herb Derby4598fa12020-06-10 14:54:22 -0400105#if GR_TEST_UTILS
Brian Salomoneebe7352020-12-09 16:37:04 -0500106 static GrOp::Owner CreateOpTestingOnly(GrSurfaceDrawContext* rtc,
Herb Derbyc76d4092020-10-07 16:46:15 -0400107 const SkPaint& skPaint,
108 const SkFont& font,
109 const SkMatrixProvider& mtxProvider,
110 const char* text,
111 int x,
112 int y);
Herb Derby4598fa12020-06-10 14:54:22 -0400113#endif
114
joshualitta751c972015-11-20 13:37:32 -0800115private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400116 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400117
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500118 struct FlushInfo {
119 sk_sp<const GrBuffer> fVertexBuffer;
120 sk_sp<const GrBuffer> fIndexBuffer;
121 GrGeometryProcessor* fGeometryProcessor;
122 const GrSurfaceProxy** fPrimProcProxies;
123 int fGlyphsToFlush = 0;
124 int fVertexOffset = 0;
125 int fNumDraws = 0;
126 };
127
Herb Derby3c873af2020-04-29 15:56:07 -0400128 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -0400129 bool needsTransform,
130 int glyphCount,
131 SkRect deviceRect,
Herb Derby6b748e42020-12-02 17:44:54 -0500132 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400133 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400134
135 GrAtlasTextOp(MaskType maskType,
136 bool needsTransform,
137 int glyphCount,
138 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -0400139 SkColor luminanceColor,
140 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -0400141 uint32_t DFGPFlags,
Herb Derby6b748e42020-12-02 17:44:54 -0500142 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400143 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800144
Robert Phillips2669a7b2020-03-12 12:07:19 -0400145 GrProgramInfo* programInfo() override {
146 // TODO [PI]: implement
147 return nullptr;
148 }
149
Herb Derby6b748e42020-12-02 17:44:54 -0500150 void addGeometry(Geometry* geometry) {
151 *fTail = geometry;
152 // The geometry may have many entries. Find the end.
153 do {
154 fTail = &(*fTail)->fNext;
155 } while (*fTail != nullptr);
156 }
157
Robert Phillips4133dc42020-03-11 15:55:55 -0400158 void onCreateProgramInfo(const GrCaps*,
159 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500160 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400161 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400162 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500163 GrXferBarrierFlags renderPassXferBarriers,
164 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400165 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
166 // implemented, the GP is modified at flush time based on the number of pages in the
167 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400168 }
169
Robert Phillips2669a7b2020-03-12 12:07:19 -0400170 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500171 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400172 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400173 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500174 GrXferBarrierFlags renderPassXferBarriers,
175 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400176 // TODO [PI]: implement
177 }
178
Brian Salomon91326c32017-08-09 16:02:19 -0400179 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700180 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800181
John Stilesaf366522020-08-13 09:57:34 -0400182#if GR_TEST_UTILS
183 SkString onDumpInfo() const override;
184#endif
185
joshualitta751c972015-11-20 13:37:32 -0800186 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500187 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500188 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800189 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500190 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800191 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500192 case MaskType::kGrayscaleCoverage:
193 case MaskType::kAliasedDistanceField:
194 case MaskType::kGrayscaleDistanceField:
195 case MaskType::kLCDDistanceField:
196 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800197 return kA8_GrMaskFormat;
198 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500199 // SkUNREACHABLE;
200 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800201 }
202
203 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500204 return MaskType::kAliasedDistanceField == this->maskType() ||
205 MaskType::kGrayscaleDistanceField == this->maskType() ||
206 MaskType::kLCDDistanceField == this->maskType() ||
207 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800208 }
209
210 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500211 return MaskType::kLCDCoverage == this->maskType() ||
212 MaskType::kLCDDistanceField == this->maskType() ||
213 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800214 }
215
Herb Derby4513cdd2020-01-31 13:28:49 -0500216 inline void createDrawForGeneratedGlyphs(
217 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800218
Michael Ludwigefc89d22020-11-05 11:43:10 -0500219 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800220
Herb Derbye25c3002020-10-27 15:57:27 -0400221 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800222
Robert Phillips841c9a52020-03-27 12:41:31 -0400223 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
224 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500225 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500226 const GrSurfaceProxyView* views,
227 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800228
Michael Ludwigefc89d22020-11-05 11:43:10 -0500229 GrProcessorSet fProcessors;
230 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
231
232 // All combinable atlas ops have equal bit field values
233 uint32_t fDFGPFlags : 9; // Distance field properties
234 uint32_t fMaskType : 3; // MaskType
235 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
236 uint32_t fNeedsGlyphTransform : 1;
237 uint32_t fHasPerspective : 1; // True if perspective affects draw
238 uint32_t fUseGammaCorrectDistanceTable : 1;
239 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
240 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
241
242 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
243 // for single-channel distance fields.
244 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800245
Herb Derby6b748e42020-12-02 17:44:54 -0500246 Geometry* fHead{nullptr};
247 Geometry** fTail{&fHead};
248
John Stiles7571f9e2020-09-02 22:42:33 -0400249 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800250};
251
joshualitta751c972015-11-20 13:37:32 -0800252#endif