blob: 95b5bcaec010803b17673fec81be86316cdf75c1 [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,
Chris Dalton6aaf00f2021-07-13 13:26:39 -0600174 bool usesMSAASurface,
Robert Phillips4133dc42020-03-11 15:55:55 -0400175 GrAppliedClip&&,
John Stiles52cb1d02021-06-02 11:58:05 -0400176 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500177 GrXferBarrierFlags renderPassXferBarriers,
178 GrLoadOp colorLoadOp) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400179 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
180 // implemented, the GP is modified at flush time based on the number of pages in the
181 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400182 }
183
Robert Phillips2669a7b2020-03-12 12:07:19 -0400184 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500185 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400186 GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -0400187 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500188 GrXferBarrierFlags renderPassXferBarriers,
189 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400190 // TODO [PI]: implement
191 }
192
Robert Phillips71143952021-06-17 14:55:07 -0400193 void onPrepareDraws(GrMeshDrawTarget*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700194 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800195
John Stilesaf366522020-08-13 09:57:34 -0400196#if GR_TEST_UTILS
197 SkString onDumpInfo() const override;
198#endif
199
joshualitta751c972015-11-20 13:37:32 -0800200 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500201 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500202 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800203 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500204 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800205 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500206 case MaskType::kGrayscaleCoverage:
207 case MaskType::kAliasedDistanceField:
208 case MaskType::kGrayscaleDistanceField:
209 case MaskType::kLCDDistanceField:
210 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800211 return kA8_GrMaskFormat;
212 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500213 // SkUNREACHABLE;
214 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800215 }
216
217 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500218 return MaskType::kAliasedDistanceField == this->maskType() ||
219 MaskType::kGrayscaleDistanceField == this->maskType() ||
220 MaskType::kLCDDistanceField == this->maskType() ||
221 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800222 }
223
224 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500225 return MaskType::kLCDCoverage == this->maskType() ||
226 MaskType::kLCDDistanceField == this->maskType() ||
227 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800228 }
229
Herb Derby4513cdd2020-01-31 13:28:49 -0500230 inline void createDrawForGeneratedGlyphs(
Robert Phillips71143952021-06-17 14:55:07 -0400231 GrMeshDrawTarget* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800232
Michael Ludwigefc89d22020-11-05 11:43:10 -0500233 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800234
Herb Derbye25c3002020-10-27 15:57:27 -0400235 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800236
Robert Phillips841c9a52020-03-27 12:41:31 -0400237 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
238 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500239 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500240 const GrSurfaceProxyView* views,
241 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800242
Michael Ludwigefc89d22020-11-05 11:43:10 -0500243 GrProcessorSet fProcessors;
244 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
245
246 // All combinable atlas ops have equal bit field values
247 uint32_t fDFGPFlags : 9; // Distance field properties
248 uint32_t fMaskType : 3; // MaskType
249 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
250 uint32_t fNeedsGlyphTransform : 1;
251 uint32_t fHasPerspective : 1; // True if perspective affects draw
252 uint32_t fUseGammaCorrectDistanceTable : 1;
253 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
254 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
255
256 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
257 // for single-channel distance fields.
258 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800259
Herb Derby6b748e42020-12-02 17:44:54 -0500260 Geometry* fHead{nullptr};
261 Geometry** fTail{&fHead};
262
John Stiles7571f9e2020-09-02 22:42:33 -0400263 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800264};
265
joshualitta751c972015-11-20 13:37:32 -0800266#endif