blob: b0a333a481236a98c2fd8319020f96af2314f41c [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 Derbybba18802021-03-31 16:45:54 -040028 for (const Geometry* g = fHead; g != nullptr;) {
29 const Geometry* next = g->fNext;
Herb Derby0b1228d2021-04-05 18:38:35 -040030 g->~Geometry();
Herb Derbybba18802021-03-31 16:45:54 -040031 g = next;
Brian Salomonf8334782017-01-03 09:42:58 -050032 }
33 }
34
Herb Derby32302552021-03-11 18:27:35 -050035#if defined(GR_HAS_THREAD_LOCAL)
Herb Derby93330c92021-02-26 12:18:26 -050036 void* operator new(size_t s);
37 void operator delete(void* b) noexcept;
38 static void ClearCache();
Robert Phillipse44c4842021-03-15 21:27:19 +000039#else
40 static void ClearCache() {}
Herb Derby93330c92021-02-26 12:18:26 -050041#endif
42
Herb Derby252a3c02020-07-14 12:15:34 -040043 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080044 static const int kIndicesPerGlyph = 6;
45
joshualitta751c972015-11-20 13:37:32 -080046 struct Geometry {
Herb Derbyeeb30ae2021-02-17 11:27:59 -050047 Geometry(const GrAtlasSubRun& subRun,
48 const SkMatrix& drawMatrix,
49 SkPoint drawOrigin,
50 SkIRect clipRect,
Herb Derby4f78f232021-02-18 10:42:35 -050051 sk_sp<GrTextBlob> blob,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050052 GrAtlasSubRunOwner subRunOwner,
Herb Derbyeeb30ae2021-02-17 11:27:59 -050053 const SkPMColor4f& color)
54 : fSubRun{subRun}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050055 , fBlob{std::move(blob)}
56 , fSubRunDtor{std::move(subRunOwner)}
Herb Derbyeeb30ae2021-02-17 11:27:59 -050057 , fDrawMatrix{drawMatrix}
58 , fDrawOrigin{drawOrigin}
59 , fClipRect{clipRect}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050060 , fColor{color} {
61 SkASSERT(fBlob != nullptr || fSubRunDtor != nullptr);
62 SkASSERT(SkToBool(fSubRunDtor) != SkToBool(fBlob));
63 }
Herb Derby6b748e42020-12-02 17:44:54 -050064
Herb Derbybba18802021-03-31 16:45:54 -040065 static Geometry* MakeForBlob(const GrAtlasSubRun& subRun,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050066 const SkMatrix& drawMatrix,
67 SkPoint drawOrigin,
68 SkIRect clipRect,
69 sk_sp<GrTextBlob> blob,
Herb Derby0b1228d2021-04-05 18:38:35 -040070 const SkPMColor4f& color,
71 SkArenaAlloc* alloc);
Herb Derby2e0b5bb2020-11-19 11:03:50 -050072
Herb Derby64391c42020-05-16 14:32:15 -040073 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040074
Herb Derby43ad7912020-07-20 16:14:19 -040075 const GrAtlasSubRun& fSubRun;
Herb Derby2e0b5bb2020-11-19 11:03:50 -050076
77 // Either this Geometry holds a ref to the GrTextBlob in the case of a text blob based
78 // SubRun (WithCaching case), or it holds a unique_ptr to a SubRun allocated on the
79 // GrTextBlobAllocator in the NoCache case. It must hold one, and can't hold both.
80 sk_sp<GrTextBlob> fBlob; // mutable to make unref call in Op dtor.
81 GrAtlasSubRunOwner fSubRunDtor;
82
Herb Derbyeeb30ae2021-02-17 11:27:59 -050083 const SkMatrix fDrawMatrix;
84 const SkPoint fDrawOrigin;
Herb Derby4f78f232021-02-18 10:42:35 -050085
Herb Derby6b748e42020-12-02 17:44:54 -050086 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
87 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050088 const SkIRect fClipRect;
Herb Derby1d17e492020-07-21 11:45:04 -040089
Michael Ludwigefc89d22020-11-05 11:43:10 -050090 // Color is updated after processor analysis if it was determined the shader resolves to
91 // a constant color that we then evaluate on the CPU.
92 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050093 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050094 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080095 };
96
Brian Salomon344ec422016-12-15 10:58:41 -050097 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080098
Robert Phillips294723d2021-06-17 09:23:58 -040099 void visitProxies(const GrVisitProxyFunc&) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400100
Brian Salomon44acb5b2017-07-18 19:59:24 -0400101 FixedFunctionFlags fixedFunctionFlags() const override;
102
Chris Dalton57ab06c2021-04-22 12:57:28 -0600103 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400104
Michael Ludwig136d8782020-11-03 11:04:16 -0500105 enum class MaskType : uint32_t {
106 kGrayscaleCoverage,
107 kLCDCoverage,
108 kColorBitmap,
109 kAliasedDistanceField,
110 kGrayscaleDistanceField,
111 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -0500112 kLCDBGRDistanceField,
113
114 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500115 };
Michael Ludwigefc89d22020-11-05 11:43:10 -0500116 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500117
Herb Derby4598fa12020-06-10 14:54:22 -0400118#if GR_TEST_UTILS
Brian Salomoneebe7352020-12-09 16:37:04 -0500119 static GrOp::Owner CreateOpTestingOnly(GrSurfaceDrawContext* rtc,
Herb Derbyc76d4092020-10-07 16:46:15 -0400120 const SkPaint& skPaint,
121 const SkFont& font,
122 const SkMatrixProvider& mtxProvider,
123 const char* text,
124 int x,
125 int y);
Herb Derby4598fa12020-06-10 14:54:22 -0400126#endif
127
joshualitta751c972015-11-20 13:37:32 -0800128private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400129 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400130
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500131 struct FlushInfo {
132 sk_sp<const GrBuffer> fVertexBuffer;
133 sk_sp<const GrBuffer> fIndexBuffer;
134 GrGeometryProcessor* fGeometryProcessor;
135 const GrSurfaceProxy** fPrimProcProxies;
136 int fGlyphsToFlush = 0;
137 int fVertexOffset = 0;
138 int fNumDraws = 0;
139 };
140
Herb Derby3c873af2020-04-29 15:56:07 -0400141 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -0400142 bool needsTransform,
143 int glyphCount,
144 SkRect deviceRect,
Herb Derby6b748e42020-12-02 17:44:54 -0500145 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400146 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400147
148 GrAtlasTextOp(MaskType maskType,
149 bool needsTransform,
150 int glyphCount,
151 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -0400152 SkColor luminanceColor,
153 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -0400154 uint32_t DFGPFlags,
Herb Derby6b748e42020-12-02 17:44:54 -0500155 Geometry* geo,
Herb Derby1d17e492020-07-21 11:45:04 -0400156 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800157
Robert Phillips2669a7b2020-03-12 12:07:19 -0400158 GrProgramInfo* programInfo() override {
159 // TODO [PI]: implement
160 return nullptr;
161 }
162
Herb Derby6b748e42020-12-02 17:44:54 -0500163 void addGeometry(Geometry* geometry) {
164 *fTail = geometry;
165 // The geometry may have many entries. Find the end.
166 do {
167 fTail = &(*fTail)->fNext;
168 } while (*fTail != nullptr);
169 }
170
Robert Phillips4133dc42020-03-11 15:55:55 -0400171 void onCreateProgramInfo(const GrCaps*,
172 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500173 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400174 GrAppliedClip&&,
John Stiles52cb1d02021-06-02 11:58:05 -0400175 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500176 GrXferBarrierFlags renderPassXferBarriers,
177 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400178 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
179 // implemented, the GP is modified at flush time based on the number of pages in the
180 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400181 }
182
Robert Phillips2669a7b2020-03-12 12:07:19 -0400183 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500184 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400185 GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -0400186 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500187 GrXferBarrierFlags renderPassXferBarriers,
188 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400189 // TODO [PI]: implement
190 }
191
Robert Phillips71143952021-06-17 14:55:07 -0400192 void onPrepareDraws(GrMeshDrawTarget*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700193 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800194
John Stilesaf366522020-08-13 09:57:34 -0400195#if GR_TEST_UTILS
196 SkString onDumpInfo() const override;
197#endif
198
joshualitta751c972015-11-20 13:37:32 -0800199 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500200 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500201 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800202 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500203 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800204 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500205 case MaskType::kGrayscaleCoverage:
206 case MaskType::kAliasedDistanceField:
207 case MaskType::kGrayscaleDistanceField:
208 case MaskType::kLCDDistanceField:
209 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800210 return kA8_GrMaskFormat;
211 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500212 // SkUNREACHABLE;
213 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800214 }
215
216 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500217 return MaskType::kAliasedDistanceField == this->maskType() ||
218 MaskType::kGrayscaleDistanceField == this->maskType() ||
219 MaskType::kLCDDistanceField == this->maskType() ||
220 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800221 }
222
223 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500224 return MaskType::kLCDCoverage == this->maskType() ||
225 MaskType::kLCDDistanceField == this->maskType() ||
226 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800227 }
228
Herb Derby4513cdd2020-01-31 13:28:49 -0500229 inline void createDrawForGeneratedGlyphs(
Robert Phillips71143952021-06-17 14:55:07 -0400230 GrMeshDrawTarget* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800231
Michael Ludwigefc89d22020-11-05 11:43:10 -0500232 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800233
Herb Derbye25c3002020-10-27 15:57:27 -0400234 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800235
Robert Phillips841c9a52020-03-27 12:41:31 -0400236 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
237 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500238 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500239 const GrSurfaceProxyView* views,
240 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800241
Michael Ludwigefc89d22020-11-05 11:43:10 -0500242 GrProcessorSet fProcessors;
243 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
244
245 // All combinable atlas ops have equal bit field values
246 uint32_t fDFGPFlags : 9; // Distance field properties
247 uint32_t fMaskType : 3; // MaskType
248 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
249 uint32_t fNeedsGlyphTransform : 1;
250 uint32_t fHasPerspective : 1; // True if perspective affects draw
251 uint32_t fUseGammaCorrectDistanceTable : 1;
252 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
253 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
254
255 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
256 // for single-channel distance fields.
257 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800258
Herb Derby6b748e42020-12-02 17:44:54 -0500259 Geometry* fHead{nullptr};
260 Geometry** fTail{&fHead};
261
John Stiles7571f9e2020-09-02 22:42:33 -0400262 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800263};
264
joshualitta751c972015-11-20 13:37:32 -0800265#endif