blob: 3b9a6baafbe31de359b28993cfa4378ec0d36eb1 [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
Robert Phillipsb97da532019-02-12 15:24:12 -050016class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050017
Brian Salomon44acb5b2017-07-18 19:59:24 -040018class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080019public:
Brian Salomon25a88092016-12-01 09:36:50 -050020 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080021
Brian Salomonf8334782017-01-03 09:42:58 -050022 ~GrAtlasTextOp() override {
Michael Ludwig64596c52020-11-05 12:39:13 -050023 for (const auto& g : fGeometries.items()) {
24 g.fBlob->unref();
Brian Salomonf8334782017-01-03 09:42:58 -050025 }
26 }
27
Herb Derby252a3c02020-07-14 12:15:34 -040028 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080029 static const int kIndicesPerGlyph = 6;
30
joshualitta751c972015-11-20 13:37:32 -080031 struct Geometry {
Herb Derby64391c42020-05-16 14:32:15 -040032 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040033
Herb Derby43ad7912020-07-20 16:14:19 -040034 const GrAtlasSubRun& fSubRun;
Herb Derby1d17e492020-07-21 11:45:04 -040035 const SkMatrix fDrawMatrix;
36 const SkPoint fDrawOrigin;
37 const SkIRect fClipRect;
38 GrTextBlob* const fBlob; // mutable to make unref call in Op dtor.
39
Michael Ludwigefc89d22020-11-05 11:43:10 -050040 // Color is updated after processor analysis if it was determined the shader resolves to
41 // a constant color that we then evaluate on the CPU.
42 // TODO: This can be made const once processor analysis is separated from op creation.
Herb Derby1d17e492020-07-21 11:45:04 -040043 SkPMColor4f fColor;
joshualitta751c972015-11-20 13:37:32 -080044 };
45
Brian Salomon344ec422016-12-15 10:58:41 -050046 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080047
Chris Dalton1706cbf2019-05-21 19:35:29 -060048 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040049
Brian Salomon44acb5b2017-07-18 19:59:24 -040050 FixedFunctionFlags fixedFunctionFlags() const override;
51
Chris Dalton6ce447a2019-06-23 18:07:38 -060052 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
53 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040054
Michael Ludwig136d8782020-11-03 11:04:16 -050055 enum class MaskType : uint32_t {
56 kGrayscaleCoverage,
57 kLCDCoverage,
58 kColorBitmap,
59 kAliasedDistanceField,
60 kGrayscaleDistanceField,
61 kLCDDistanceField,
Michael Ludwigefc89d22020-11-05 11:43:10 -050062 kLCDBGRDistanceField,
63
64 kLast = kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -050065 };
Michael Ludwigefc89d22020-11-05 11:43:10 -050066 static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050067
Herb Derby4598fa12020-06-10 14:54:22 -040068#if GR_TEST_UTILS
Herb Derbyc76d4092020-10-07 16:46:15 -040069 static GrOp::Owner CreateOpTestingOnly(GrRenderTargetContext* rtc,
70 const SkPaint& skPaint,
71 const SkFont& font,
72 const SkMatrixProvider& mtxProvider,
73 const char* text,
74 int x,
75 int y);
Herb Derby4598fa12020-06-10 14:54:22 -040076#endif
77
joshualitta751c972015-11-20 13:37:32 -080078private:
Herb Derbyc76d4092020-10-07 16:46:15 -040079 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -040080
Herb Derby3c873af2020-04-29 15:56:07 -040081 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -040082 bool needsTransform,
83 int glyphCount,
84 SkRect deviceRect,
Herb Derby1d17e492020-07-21 11:45:04 -040085 const Geometry& geo,
86 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -040087
88 GrAtlasTextOp(MaskType maskType,
89 bool needsTransform,
90 int glyphCount,
91 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -040092 SkColor luminanceColor,
93 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -040094 uint32_t DFGPFlags,
Herb Derby1d17e492020-07-21 11:45:04 -040095 const Geometry& geo,
96 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -080097
98 struct FlushInfo {
Brian Salomon344ec422016-12-15 10:58:41 -050099 sk_sp<const GrBuffer> fVertexBuffer;
100 sk_sp<const GrBuffer> fIndexBuffer;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500101 GrGeometryProcessor* fGeometryProcessor;
Chris Dalton304e14d2020-03-17 14:29:06 -0600102 const GrSurfaceProxy** fPrimProcProxies;
Brian Salomon43cbd722020-01-03 22:09:12 -0500103 int fGlyphsToFlush = 0;
104 int fVertexOffset = 0;
105 int fNumDraws = 0;
joshualitta751c972015-11-20 13:37:32 -0800106 };
107
Robert Phillips2669a7b2020-03-12 12:07:19 -0400108 GrProgramInfo* programInfo() override {
109 // TODO [PI]: implement
110 return nullptr;
111 }
112
Robert Phillips4133dc42020-03-11 15:55:55 -0400113 void onCreateProgramInfo(const GrCaps*,
114 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500115 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400116 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400117 const GrXferProcessor::DstProxyView&,
118 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400119 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
120 // implemented, the GP is modified at flush time based on the number of pages in the
121 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400122 }
123
Robert Phillips2669a7b2020-03-12 12:07:19 -0400124 void onPrePrepareDraws(GrRecordingContext*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500125 const GrSurfaceProxyView& writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400126 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400127 const GrXferProcessor::DstProxyView&,
128 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400129 // TODO [PI]: implement
130 }
131
Brian Salomon91326c32017-08-09 16:02:19 -0400132 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700133 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800134
John Stilesaf366522020-08-13 09:57:34 -0400135#if GR_TEST_UTILS
136 SkString onDumpInfo() const override;
137#endif
138
joshualitta751c972015-11-20 13:37:32 -0800139 GrMaskFormat maskFormat() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500140 switch (this->maskType()) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500141 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800142 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500143 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800144 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500145 case MaskType::kGrayscaleCoverage:
146 case MaskType::kAliasedDistanceField:
147 case MaskType::kGrayscaleDistanceField:
148 case MaskType::kLCDDistanceField:
149 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800150 return kA8_GrMaskFormat;
151 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500152 // SkUNREACHABLE;
153 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800154 }
155
156 bool usesDistanceFields() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500157 return MaskType::kAliasedDistanceField == this->maskType() ||
158 MaskType::kGrayscaleDistanceField == this->maskType() ||
159 MaskType::kLCDDistanceField == this->maskType() ||
160 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800161 }
162
163 bool isLCD() const {
Michael Ludwigefc89d22020-11-05 11:43:10 -0500164 return MaskType::kLCDCoverage == this->maskType() ||
165 MaskType::kLCDDistanceField == this->maskType() ||
166 MaskType::kLCDBGRDistanceField == this->maskType();
joshualitta751c972015-11-20 13:37:32 -0800167 }
168
Herb Derby4513cdd2020-01-31 13:28:49 -0500169 inline void createDrawForGeneratedGlyphs(
170 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800171
Michael Ludwigefc89d22020-11-05 11:43:10 -0500172 MaskType maskType() const { return static_cast<MaskType>(fMaskType); }
joshualitta751c972015-11-20 13:37:32 -0800173
Herb Derbye25c3002020-10-27 15:57:27 -0400174 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800175
Robert Phillips841c9a52020-03-27 12:41:31 -0400176 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
177 const GrShaderCaps&,
Michael Ludwig9597e2f2020-11-03 11:06:25 -0500178 const SkMatrix& localMatrix,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500179 const GrSurfaceProxyView* views,
180 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800181
Michael Ludwig64596c52020-11-05 12:39:13 -0500182 // The minimum number of Geometry we will try to allocate as ops are merged together.
183 // The atlas text op holds one Geometry inline. When combined with the linear growth policy,
184 // the total number of geometries follows 6, 18, 36, 60, 90 (the deltas are 6*n).
185 static constexpr auto kMinGeometryAllocated = 6;
186
187 GrTBlockList<Geometry> fGeometries{kMinGeometryAllocated,
188 GrBlockAllocator::GrowthPolicy::kLinear};
Michael Ludwigefc89d22020-11-05 11:43:10 -0500189
190 GrProcessorSet fProcessors;
191 int fNumGlyphs; // Sum of glyphs in each geometry's subrun
192
193 // All combinable atlas ops have equal bit field values
194 uint32_t fDFGPFlags : 9; // Distance field properties
195 uint32_t fMaskType : 3; // MaskType
196 uint32_t fUsesLocalCoords : 1; // Filled in post processor analysis
197 uint32_t fNeedsGlyphTransform : 1;
198 uint32_t fHasPerspective : 1; // True if perspective affects draw
199 uint32_t fUseGammaCorrectDistanceTable : 1;
200 static_assert(kMaskTypeCount <= 8, "MaskType does not fit in 3 bits");
201 static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 8), "DFGP Flags do not fit in 9 bits");
202
203 // Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
204 // for single-channel distance fields.
205 const SkColor fLuminanceColor{0};
joshualitta751c972015-11-20 13:37:32 -0800206
John Stiles7571f9e2020-09-02 22:42:33 -0400207 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800208};
209
joshualitta751c972015-11-20 13:37:32 -0800210#endif