blob: 5f9fc836e5a73a63786c8fbe8de08d57f1b78b95 [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
Robert Phillipsb97da532019-02-12 15:24:12 -050015class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050016
Robert Phillips31f76312021-08-27 12:35:41 -040017namespace skgpu::v1 {
18
19class AtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080020public:
Brian Salomon25a88092016-12-01 09:36:50 -050021 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080022
Robert Phillips31f76312021-08-27 12:35:41 -040023 ~AtlasTextOp() override {
Herb Derbybba18802021-03-31 16:45:54 -040024 for (const Geometry* g = fHead; g != nullptr;) {
25 const Geometry* next = g->fNext;
Herb Derby0b1228d2021-04-05 18:38:35 -040026 g->~Geometry();
Herb Derbybba18802021-03-31 16:45:54 -040027 g = next;
Brian Salomonf8334782017-01-03 09:42:58 -050028 }
29 }
30
Herb Derby93330c92021-02-26 12:18:26 -050031 void* operator new(size_t s);
32 void operator delete(void* b) noexcept;
33 static void ClearCache();
Herb Derby93330c92021-02-26 12:18:26 -050034
Herb Derby252a3c02020-07-14 12:15:34 -040035 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080036 static const int kIndicesPerGlyph = 6;
37
joshualitta751c972015-11-20 13:37:32 -080038 struct Geometry {
Herb Derbyeeb30ae2021-02-17 11:27:59 -050039 Geometry(const GrAtlasSubRun& subRun,
40 const SkMatrix& drawMatrix,
41 SkPoint drawOrigin,
42 SkIRect clipRect,
Herb Derby4f78f232021-02-18 10:42:35 -050043 sk_sp<GrTextBlob> blob,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050044 GrAtlasSubRunOwner subRunOwner,
Herb Derbyeeb30ae2021-02-17 11:27:59 -050045 const SkPMColor4f& color)
46 : fSubRun{subRun}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050047 , fBlob{std::move(blob)}
48 , fSubRunDtor{std::move(subRunOwner)}
Herb Derbyeeb30ae2021-02-17 11:27:59 -050049 , fDrawMatrix{drawMatrix}
50 , fDrawOrigin{drawOrigin}
51 , fClipRect{clipRect}
Herb Derby2e0b5bb2020-11-19 11:03:50 -050052 , fColor{color} {
53 SkASSERT(fBlob != nullptr || fSubRunDtor != nullptr);
54 SkASSERT(SkToBool(fSubRunDtor) != SkToBool(fBlob));
55 }
Herb Derby6b748e42020-12-02 17:44:54 -050056
Herb Derbybba18802021-03-31 16:45:54 -040057 static Geometry* MakeForBlob(const GrAtlasSubRun& subRun,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050058 const SkMatrix& drawMatrix,
59 SkPoint drawOrigin,
60 SkIRect clipRect,
61 sk_sp<GrTextBlob> blob,
Herb Derby0b1228d2021-04-05 18:38:35 -040062 const SkPMColor4f& color,
63 SkArenaAlloc* alloc);
Herb Derby2e0b5bb2020-11-19 11:03:50 -050064
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 Derby2e0b5bb2020-11-19 11:03:50 -050068
69 // Either this Geometry holds a ref to the GrTextBlob in the case of a text blob based
70 // SubRun (WithCaching case), or it holds a unique_ptr to a SubRun allocated on the
71 // GrTextBlobAllocator in the NoCache case. It must hold one, and can't hold both.
72 sk_sp<GrTextBlob> fBlob; // mutable to make unref call in Op dtor.
73 GrAtlasSubRunOwner fSubRunDtor;
74
Herb Derbyeeb30ae2021-02-17 11:27:59 -050075 const SkMatrix fDrawMatrix;
76 const SkPoint fDrawOrigin;
Herb Derby4f78f232021-02-18 10:42:35 -050077
Herb Derby6b748e42020-12-02 17:44:54 -050078 // fClipRect is only used in the DirectMaskSubRun case to do geometric clipping.
79 // TransformedMaskSubRun, and SDFTSubRun don't use this field, and expect an empty rect.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050080 const SkIRect fClipRect;
Herb Derby1d17e492020-07-21 11:45:04 -040081
Michael Ludwigefc89d22020-11-05 11:43:10 -050082 // Color is updated after processor analysis if it was determined the shader resolves to
83 // a constant color that we then evaluate on the CPU.
84 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derbyeeb30ae2021-02-17 11:27:59 -050085 SkPMColor4f fColor;
Herb Derby6b748e42020-12-02 17:44:54 -050086 Geometry* fNext{nullptr};
joshualitta751c972015-11-20 13:37:32 -080087 };
88
Brian Salomon344ec422016-12-15 10:58:41 -050089 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080090
Robert Phillips294723d2021-06-17 09:23:58 -040091 void visitProxies(const GrVisitProxyFunc&) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040092
Brian Salomon44acb5b2017-07-18 19:59:24 -040093 FixedFunctionFlags fixedFunctionFlags() const override;
94
Chris Dalton57ab06c2021-04-22 12:57:28 -060095 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040096
Michael Ludwig136d8782020-11-03 11:04:16 -050097 enum class MaskType : uint32_t {
98 kGrayscaleCoverage,
99 kLCDCoverage,
100 kColorBitmap,
101 kAliasedDistanceField,
102 kGrayscaleDistanceField,
103 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -0500104 kLCDBGRDistanceField,
105
106 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500107 };
Michael Ludwigefc89d22020-11-05 11:43:10 -0500108 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500109
Robert Phillipsa3f206e2021-08-02 13:27:05 -0400110#if GR_TEST_UTILS && SK_GPU_V1
Robert Phillips4dca8312021-07-28 15:13:20 -0400111 static GrOp::Owner CreateOpTestingOnly(skgpu::v1::SurfaceDrawContext*,
112 const SkPaint&,
113 const SkFont&,
114 const SkMatrixProvider&,
Herb Derbyc76d4092020-10-07 16:46:15 -0400115 const char* text,
116 int x,
117 int y);
Herb Derby4598fa12020-06-10 14:54:22 -0400118#endif
119
joshualitta751c972015-11-20 13:37:32 -0800120private:
Herb Derbyc76d4092020-10-07 16:46:15 -0400121 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -0400122
Herb Derbyeeb30ae2021-02-17 11:27:59 -0500123 struct FlushInfo {
124 sk_sp<const GrBuffer> fVertexBuffer;
125 sk_sp<const GrBuffer> fIndexBuffer;
126 GrGeometryProcessor* fGeometryProcessor;
127 const GrSurfaceProxy** fPrimProcProxies;
128 int fGlyphsToFlush = 0;
129 int fVertexOffset = 0;
130 int fNumDraws = 0;
131 };
132
Robert Phillips31f76312021-08-27 12:35:41 -0400133 AtlasTextOp(MaskType maskType,
134 bool needsTransform,
135 int glyphCount,
136 SkRect deviceRect,
137 Geometry* geo,
138 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -0400139
Robert Phillips31f76312021-08-27 12:35:41 -0400140 AtlasTextOp(MaskType maskType,
141 bool needsTransform,
142 int glyphCount,
143 SkRect deviceRect,
144 SkColor luminanceColor,
145 bool useGammaCorrectDistanceTable,
146 uint32_t DFGPFlags,
147 Geometry* geo,
148 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -0800149
Robert Phillips2669a7b2020-03-12 12:07:19 -0400150 GrProgramInfo* programInfo() override {
151 // TODO [PI]: implement
152 return nullptr;
153 }
154
Herb Derby6b748e42020-12-02 17:44:54 -0500155 void addGeometry(Geometry* geometry) {
156 *fTail = geometry;
157 // The geometry may have many entries. Find the end.
158 do {
159 fTail = &(*fTail)->fNext;
160 } while (*fTail != nullptr);
161 }
162
Robert Phillips4133dc42020-03-11 15:55:55 -0400163 void onCreateProgramInfo(const GrCaps*,
164 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500165 const GrSurfaceProxyView& writeView,
Chris Dalton6aaf00f2021-07-13 13:26:39 -0600166 bool usesMSAASurface,
Robert Phillips4133dc42020-03-11 15:55:55 -0400167 GrAppliedClip&&,
John Stiles52cb1d02021-06-02 11:58:05 -0400168 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500169 GrXferBarrierFlags renderPassXferBarriers,
170 GrLoadOp colorLoadOp) override {
Robert Phillips31f76312021-08-27 12:35:41 -0400171 // We cannot surface the AtlasTextOp's programInfo at record time. As currently
Robert Phillips326f1d72020-10-01 09:43:29 -0400172 // implemented, the GP is modified at flush time based on the number of pages in the
173 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400174 }
175
Robert Phillips2669a7b2020-03-12 12:07:19 -0400176 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500177 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400178 GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -0400179 const GrDstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500180 GrXferBarrierFlags renderPassXferBarriers,
181 GrLoadOp colorLoadOp) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400182 // TODO [PI]: implement
183 }
184
Robert Phillips71143952021-06-17 14:55:07 -0400185 void onPrepareDraws(GrMeshDrawTarget*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700186 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800187
John Stilesaf366522020-08-13 09:57:34 -0400188#if GR_TEST_UTILS
189 SkString onDumpInfo() const override;
190#endif
191
joshualitta751c972015-11-20 13:37:32 -0800192 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500193 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500194 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800195 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500196 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800197 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500198 case MaskType::kGrayscaleCoverage:
199 case MaskType::kAliasedDistanceField:
200 case MaskType::kGrayscaleDistanceField:
201 case MaskType::kLCDDistanceField:
202 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800203 return kA8_GrMaskFormat;
204 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500205 // SkUNREACHABLE;
206 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800207 }
208
209 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500210 return MaskType::kAliasedDistanceField == this->maskType() ||
211 MaskType::kGrayscaleDistanceField == this->maskType() ||
212 MaskType::kLCDDistanceField == this->maskType() ||
213 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800214 }
215
216 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500217 return MaskType::kLCDCoverage == this->maskType() ||
218 MaskType::kLCDDistanceField == this->maskType() ||
219 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800220 }
221
Herb Derby4513cdd2020-01-31 13:28:49 -0500222 inline void createDrawForGeneratedGlyphs(
Robert Phillips71143952021-06-17 14:55:07 -0400223 GrMeshDrawTarget* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800224
Michael Ludwigefc89d22020-11-05 11:43:10 -0500225 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800226
Herb Derbye25c3002020-10-27 15:57:27 -0400227 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800228
Robert Phillips841c9a52020-03-27 12:41:31 -0400229 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
230 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500231 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500232 const GrSurfaceProxyView* views,
233 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800234
Michael Ludwigefc89d22020-11-05 11:43:10 -0500235 GrProcessorSet fProcessors;
236 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
237
238 // All combinable atlas ops have equal bit field values
239 uint32_t fDFGPFlags : 9; // Distance field properties
240 uint32_t fMaskType : 3; // MaskType
241 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
242 uint32_t fNeedsGlyphTransform : 1;
243 uint32_t fHasPerspective : 1; // True if perspective affects draw
244 uint32_t fUseGammaCorrectDistanceTable : 1;
245 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
246 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
247
248 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
249 // for single-channel distance fields.
250 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800251
Herb Derby6b748e42020-12-02 17:44:54 -0500252 Geometry* fHead{nullptr};
253 Geometry** fTail{&fHead};
254
John Stiles7571f9e2020-09-02 22:42:33 -0400255 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800256};
257
Robert Phillips31f76312021-08-27 12:35:41 -0400258} // namespace skgpu::v1
259
260#endif // AtlasTextOp_DEFINED