blob: 83df60a1143203e0255c60c4eccd981642482c50 [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
Robert Phillips31f76312021-08-27 12:35:41 -04008#ifndef AtlasTextOp_DEFINED
9#define AtlasTextOp_DEFINED
joshualitta751c972015-11-20 13:37:32 -080010
Michael Ludwigefc89d22020-11-05 11:43:10 -050011#include "src/gpu/effects/GrDistanceFieldGeoProc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/ops/GrMeshDrawOp.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/text/GrTextBlob.h"
joshualitta751c972015-11-20 13:37:32 -080014
Herb Derby93330c92021-02-26 12:18:26 -050015#if !defined(SK_BUILD_FOR_IOS) || \
16 (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_9_0)
17 #define GR_HAS_THREAD_LOCAL
18#endif
19
Robert Phillipsb97da532019-02-12 15:24:12 -050020class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050021
Robert Phillips31f76312021-08-27 12:35:41 -040022namespace skgpu::v1 {
23
24class AtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080025public:
Brian Salomon25a88092016-12-01 09:36:50 -050026 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080027
Robert Phillips31f76312021-08-27 12:35:41 -040028 ~AtlasTextOp() override {
Herb Derbybba18802021-03-31 16:45:54 -040029 for (const Geometry* g = fHead; g != nullptr;) {
30 const Geometry* next = g->fNext;
Herb Derby0b1228d2021-04-05 18:38:35 -040031 g->~Geometry();
Herb Derbybba18802021-03-31 16:45:54 -040032 g = next;
Brian Salomonf8334782017-01-03 09:42:58 -050033 }
34 }
35
Herb Derby32302552021-03-11 18:27:35 -050036#if defined(GR_HAS_THREAD_LOCAL)
Herb Derby93330c92021-02-26 12:18:26 -050037 void* operator new(size_t s);
38 void operator delete(void* b) noexcept;
39 static void ClearCache();
Robert Phillipse44c4842021-03-15 21:27:19 +000040#else
41 static void ClearCache() {}
Herb Derby93330c92021-02-26 12:18:26 -050042#endif
43
Herb Derby252a3c02020-07-14 12:15:34 -040044 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080045 static const int kIndicesPerGlyph = 6;
46
joshualitta751c972015-11-20 13:37:32 -080047 struct Geometry {
Herb Derbyeeb30ae2021-02-17 11:27:59 -050048 Geometry(const GrAtlasSubRun& subRun,
49 const SkMatrix& drawMatrix,
50 SkPoint drawOrigin,
51 SkIRect clipRect,
Herb Derby4f78f232021-02-18 10:42:35 -050052 sk_sp<GrTextBlob> blob,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050053 GrAtlasSubRunOwner subRunOwner,
Herb Derbyeeb30ae2021-02-17 11:27:59 -050054 const SkPMColor4f& color)
55 : fSubRun{subRun}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050056 , fBlob{std::move(blob)}
57 , fSubRunDtor{std::move(subRunOwner)}
Herb Derbyeeb30ae2021-02-17 11:27:59 -050058 , fDrawMatrix{drawMatrix}
59 , fDrawOrigin{drawOrigin}
60 , fClipRect{clipRect}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050061 , fColor{color} {
62 SkASSERT(fBlob != nullptr || fSubRunDtor != nullptr);
63 SkASSERT(SkToBool(fSubRunDtor) != SkToBool(fBlob));
64 }
Herb Derby6b748e42020-12-02 17:44:54 -050065
Herb Derbybba18802021-03-31 16:45:54 -040066 static Geometry* MakeForBlob(const GrAtlasSubRun& subRun,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050067 const SkMatrix& drawMatrix,
68 SkPoint drawOrigin,
69 SkIRect clipRect,
70 sk_sp<GrTextBlob> blob,
Herb Derby0b1228d2021-04-05 18:38:35 -040071 const SkPMColor4f& color,
72 SkArenaAlloc* alloc);
Herb Derby2e0b5bb2020-11-19 11:03:50 -050073
Herb Derby64391c42020-05-16 14:32:15 -040074 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040075
Herb Derby43ad7912020-07-20 16:14:19 -040076 const GrAtlasSubRun& fSubRun;
Herb Derby2e0b5bb2020-11-19 11:03:50 -050077
78 // Either this Geometry holds a ref to the GrTextBlob in the case of a text blob based
79 // SubRun (WithCaching case), or it holds a unique_ptr to a SubRun allocated on the
80 // GrTextBlobAllocator in the NoCache case. It must hold one, and can't hold both.
81 sk_sp<GrTextBlob> fBlob; // mutable to make unref call in Op dtor.
82 GrAtlasSubRunOwner fSubRunDtor;
83
Herb Derbyeeb30ae2021-02-17 11:27:59 -050084 const SkMatrix fDrawMatrix;
85 const SkPoint fDrawOrigin;
Herb Derby4f78f232021-02-18 10:42:35 -050086
Herb Derby6b748e42020-12-02 17:44:54 -050087 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
88 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050089 const SkIRect fClipRect;
Herb Derby1d17e492020-07-21 11:45:04 -040090
Michael Ludwigefc89d22020-11-05 11:43:10 -050091 // Color is updated after processor analysis if it was determined the shader resolves to
92 // a constant color that we then evaluate on the CPU.
93 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050094 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050095 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080096 };
97
Brian Salomon344ec422016-12-15 10:58:41 -050098 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080099
Robert Phillips294723d2021-06-17 09:23:58 -0400100 void visitProxies(const GrVisitProxyFunc&) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400101
Brian Salomon44acb5b2017-07-18 19:59:24 -0400102 FixedFunctionFlags fixedFunctionFlags() const override;
103
Chris Dalton57ab06c2021-04-22 12:57:28 -0600104 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400105
Michael Ludwig136d8782020-11-03 11:04:16 -0500106 enum class MaskType : uint32_t {
107 kGrayscaleCoverage,
108 kLCDCoverage,
109 kColorBitmap,
110 kAliasedDistanceField,
111 kGrayscaleDistanceField,
112 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -0500113 kLCDBGRDistanceField,
114
115 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500116 };
Michael Ludwigefc89d22020-11-05 11:43:10 -0500117 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500118
Robert Phillipsa3f206e2021-08-02 13:27:05 -0400119#if GR_TEST_UTILS && SK_GPU_V1
Robert Phillips4dca8312021-07-28 15:13:20 -0400120 static GrOp::Owner CreateOpTestingOnly(skgpu::v1::SurfaceDrawContext*,
121 const SkPaint&,
122 const SkFont&,
123 const SkMatrixProvider&,
Herb Derbyc76d4092020-10-07 16:46:15 -0400124 const char* text,
125 int x,
126 int y);
Herb Derby4598fa12020-06-10 14:54:22 -0400127#endif
128
joshualitta751c972015-11-20 13:37:32 -0800129private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400130 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400131
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500132 struct FlushInfo {
133 sk_sp<const GrBuffer> fVertexBuffer;
134 sk_sp<const GrBuffer> fIndexBuffer;
135 GrGeometryProcessor* fGeometryProcessor;
136 const GrSurfaceProxy** fPrimProcProxies;
137 int fGlyphsToFlush = 0;
138 int fVertexOffset = 0;
139 int fNumDraws = 0;
140 };
141
Robert Phillips31f76312021-08-27 12:35:41 -0400142 AtlasTextOp(MaskType maskType,
143 bool needsTransform,
144 int glyphCount,
145 SkRect deviceRect,
146 Geometry* geo,
147 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400148
Robert Phillips31f76312021-08-27 12:35:41 -0400149 AtlasTextOp(MaskType maskType,
150 bool needsTransform,
151 int glyphCount,
152 SkRect deviceRect,
153 SkColor luminanceColor,
154 bool useGammaCorrectDistanceTable,
155 uint32_t DFGPFlags,
156 Geometry* geo,
157 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800158
Robert Phillips2669a7b2020-03-12 12:07:19 -0400159 GrProgramInfo* programInfo() override {
160 // TODO [PI]: implement
161 return nullptr;
162 }
163
Herb Derby6b748e42020-12-02 17:44:54 -0500164 void addGeometry(Geometry* geometry) {
165 *fTail = geometry;
166 // The geometry may have many entries. Find the end.
167 do {
168 fTail = &(*fTail)->fNext;
169 } while (*fTail != nullptr);
170 }
171
Robert Phillips4133dc42020-03-11 15:55:55 -0400172 void onCreateProgramInfo(const GrCaps*,
173 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500174 const GrSurfaceProxyView& writeView,
Chris Dalton6aaf00f2021-07-13 13:26:39 -0600175 bool usesMSAASurface,
Robert Phillips4133dc42020-03-11 15:55:55 -0400176 GrAppliedClip&&,
John Stiles52cb1d02021-06-02 11:58:05 -0400177 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500178 GrXferBarrierFlags renderPassXferBarriers,
179 GrLoadOp colorLoadOp) override {
Robert Phillips31f76312021-08-27 12:35:41 -0400180 // We cannot surface the AtlasTextOp's programInfo at record time. As currently
Robert Phillips326f1d72020-10-01 09:43:29 -0400181 // implemented, the GP is modified at flush time based on the number of pages in the
182 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400183 }
184
Robert Phillips2669a7b2020-03-12 12:07:19 -0400185 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500186 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400187 GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -0400188 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500189 GrXferBarrierFlags renderPassXferBarriers,
190 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400191 // TODO [PI]: implement
192 }
193
Robert Phillips71143952021-06-17 14:55:07 -0400194 void onPrepareDraws(GrMeshDrawTarget*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700195 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800196
John Stilesaf366522020-08-13 09:57:34 -0400197#if GR_TEST_UTILS
198 SkString onDumpInfo() const override;
199#endif
200
joshualitta751c972015-11-20 13:37:32 -0800201 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500202 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500203 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800204 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500205 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800206 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500207 case MaskType::kGrayscaleCoverage:
208 case MaskType::kAliasedDistanceField:
209 case MaskType::kGrayscaleDistanceField:
210 case MaskType::kLCDDistanceField:
211 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800212 return kA8_GrMaskFormat;
213 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500214 // SkUNREACHABLE;
215 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800216 }
217
218 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500219 return MaskType::kAliasedDistanceField == this->maskType() ||
220 MaskType::kGrayscaleDistanceField == this->maskType() ||
221 MaskType::kLCDDistanceField == this->maskType() ||
222 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800223 }
224
225 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500226 return MaskType::kLCDCoverage == this->maskType() ||
227 MaskType::kLCDDistanceField == this->maskType() ||
228 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800229 }
230
Herb Derby4513cdd2020-01-31 13:28:49 -0500231 inline void createDrawForGeneratedGlyphs(
Robert Phillips71143952021-06-17 14:55:07 -0400232 GrMeshDrawTarget* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800233
Michael Ludwigefc89d22020-11-05 11:43:10 -0500234 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800235
Herb Derbye25c3002020-10-27 15:57:27 -0400236 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800237
Robert Phillips841c9a52020-03-27 12:41:31 -0400238 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
239 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500240 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500241 const GrSurfaceProxyView* views,
242 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800243
Michael Ludwigefc89d22020-11-05 11:43:10 -0500244 GrProcessorSet fProcessors;
245 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
246
247 // All combinable atlas ops have equal bit field values
248 uint32_t fDFGPFlags : 9; // Distance field properties
249 uint32_t fMaskType : 3; // MaskType
250 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
251 uint32_t fNeedsGlyphTransform : 1;
252 uint32_t fHasPerspective : 1; // True if perspective affects draw
253 uint32_t fUseGammaCorrectDistanceTable : 1;
254 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
255 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
256
257 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
258 // for single-channel distance fields.
259 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800260
Herb Derby6b748e42020-12-02 17:44:54 -0500261 Geometry* fHead{nullptr};
262 Geometry** fTail{&fHead};
263
John Stiles7571f9e2020-09-02 22:42:33 -0400264 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800265};
266
Robert Phillips31f76312021-08-27 12:35:41 -0400267} // namespace skgpu::v1
268
269#endif // AtlasTextOp_DEFINED