blob: 38f687aad3e397d6f3bcde1e27ff1e22e1831090 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/ops/GrMeshDrawOp.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/text/GrTextBlob.h"
joshualitta751c972015-11-20 13:37:32 -080013
Robert Phillipsb97da532019-02-12 15:24:12 -050014class GrRecordingContext;
Brian Salomoncbcb0a12017-11-19 13:20:13 -050015
Brian Salomon44acb5b2017-07-18 19:59:24 -040016class GrAtlasTextOp final : public GrMeshDrawOp {
joshualitta751c972015-11-20 13:37:32 -080017public:
Brian Salomon25a88092016-12-01 09:36:50 -050018 DEFINE_OP_CLASS_ID
joshualitta751c972015-11-20 13:37:32 -080019
Brian Salomonf8334782017-01-03 09:42:58 -050020 ~GrAtlasTextOp() override {
21 for (int i = 0; i < fGeoCount; i++) {
22 fGeoData[i].fBlob->unref();
23 }
24 }
25
Herb Derby252a3c02020-07-14 12:15:34 -040026 static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
joshualitta751c972015-11-20 13:37:32 -080027 static const int kIndicesPerGlyph = 6;
28
joshualitta751c972015-11-20 13:37:32 -080029 struct Geometry {
Herb Derby64391c42020-05-16 14:32:15 -040030 void fillVertexData(void* dst, int offset, int count) const;
Herb Derby1d17e492020-07-21 11:45:04 -040031
Herb Derby43ad7912020-07-20 16:14:19 -040032 const GrAtlasSubRun& fSubRun;
Herb Derby1d17e492020-07-21 11:45:04 -040033 const SkMatrix fDrawMatrix;
34 const SkPoint fDrawOrigin;
35 const SkIRect fClipRect;
36 GrTextBlob* const fBlob; // mutable to make unref call in Op dtor.
37
38 // Strangely, the color is mutated as part of the onPrepare process.
39 SkPMColor4f fColor;
joshualitta751c972015-11-20 13:37:32 -080040 };
41
Brian Salomon344ec422016-12-15 10:58:41 -050042 const char* name() const override { return "AtlasTextOp"; }
joshualitta751c972015-11-20 13:37:32 -080043
Chris Dalton1706cbf2019-05-21 19:35:29 -060044 void visitProxies(const VisitProxyFunc& func) const override;
Robert Phillipsb493eeb2017-09-13 13:10:52 -040045
Brian Salomon44acb5b2017-07-18 19:59:24 -040046 FixedFunctionFlags fixedFunctionFlags() const override;
47
Chris Dalton6ce447a2019-06-23 18:07:38 -060048 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
49 bool hasMixedSampledCoverage, GrClampType) override;
Brian Salomon44acb5b2017-07-18 19:59:24 -040050
Michael Ludwig136d8782020-11-03 11:04:16 -050051 enum class MaskType : uint32_t {
52 kGrayscaleCoverage,
53 kLCDCoverage,
54 kColorBitmap,
55 kAliasedDistanceField,
56 kGrayscaleDistanceField,
57 kLCDDistanceField,
58 kLCDBGRDistanceField
Brian Salomoncbcb0a12017-11-19 13:20:13 -050059 };
60
Herb Derby4598fa12020-06-10 14:54:22 -040061#if GR_TEST_UTILS
Herb Derbyc76d4092020-10-07 16:46:15 -040062 static GrOp::Owner CreateOpTestingOnly(GrRenderTargetContext* rtc,
63 const SkPaint& skPaint,
64 const SkFont& font,
65 const SkMatrixProvider& mtxProvider,
66 const char* text,
67 int x,
68 int y);
Herb Derby4598fa12020-06-10 14:54:22 -040069#endif
70
joshualitta751c972015-11-20 13:37:32 -080071private:
Herb Derbyc76d4092020-10-07 16:46:15 -040072 friend class GrOp; // for ctor
Robert Phillips7c525e62018-06-12 10:11:12 -040073
Jim Van Verthc8a65e32017-10-25 14:25:27 -040074 // The minimum number of Geometry we will try to allocate.
Jim Van Verth56c37142017-10-31 14:44:25 -040075 static constexpr auto kMinGeometryAllocated = 12;
Jim Van Verthc8a65e32017-10-25 14:25:27 -040076
Herb Derby3c873af2020-04-29 15:56:07 -040077 GrAtlasTextOp(MaskType maskType,
Herb Derby268e48b2020-07-16 12:56:58 -040078 bool needsTransform,
79 int glyphCount,
80 SkRect deviceRect,
Herb Derby1d17e492020-07-21 11:45:04 -040081 const Geometry& geo,
82 GrPaint&& paint);
Herb Derby268e48b2020-07-16 12:56:58 -040083
84 GrAtlasTextOp(MaskType maskType,
85 bool needsTransform,
86 int glyphCount,
87 SkRect deviceRect,
Herb Derby3c873af2020-04-29 15:56:07 -040088 SkColor luminanceColor,
89 bool useGammaCorrectDistanceTable,
Herb Derby268e48b2020-07-16 12:56:58 -040090 uint32_t DFGPFlags,
Herb Derby1d17e492020-07-21 11:45:04 -040091 const Geometry& geo,
92 GrPaint&& paint);
joshualitta751c972015-11-20 13:37:32 -080093
94 struct FlushInfo {
Brian Salomon344ec422016-12-15 10:58:41 -050095 sk_sp<const GrBuffer> fVertexBuffer;
96 sk_sp<const GrBuffer> fIndexBuffer;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050097 GrGeometryProcessor* fGeometryProcessor;
Chris Dalton304e14d2020-03-17 14:29:06 -060098 const GrSurfaceProxy** fPrimProcProxies;
Brian Salomon43cbd722020-01-03 22:09:12 -050099 int fGlyphsToFlush = 0;
100 int fVertexOffset = 0;
101 int fNumDraws = 0;
joshualitta751c972015-11-20 13:37:32 -0800102 };
103
Robert Phillips2669a7b2020-03-12 12:07:19 -0400104 GrProgramInfo* programInfo() override {
105 // TODO [PI]: implement
106 return nullptr;
107 }
108
Robert Phillips4133dc42020-03-11 15:55:55 -0400109 void onCreateProgramInfo(const GrCaps*,
110 SkArenaAlloc*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400111 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400112 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400113 const GrXferProcessor::DstProxyView&,
114 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips326f1d72020-10-01 09:43:29 -0400115 // We cannot surface the GrAtlasTextOp's programInfo at record time. As currently
116 // implemented, the GP is modified at flush time based on the number of pages in the
117 // atlas.
Robert Phillips4133dc42020-03-11 15:55:55 -0400118 }
119
Robert Phillips2669a7b2020-03-12 12:07:19 -0400120 void onPrePrepareDraws(GrRecordingContext*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400121 const GrSurfaceProxyView* writeView,
Robert Phillips2669a7b2020-03-12 12:07:19 -0400122 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400123 const GrXferProcessor::DstProxyView&,
124 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips2669a7b2020-03-12 12:07:19 -0400125 // TODO [PI]: implement
126 }
127
Brian Salomon91326c32017-08-09 16:02:19 -0400128 void onPrepareDraws(Target*) override;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700129 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
joshualitta751c972015-11-20 13:37:32 -0800130
John Stilesaf366522020-08-13 09:57:34 -0400131#if GR_TEST_UTILS
132 SkString onDumpInfo() const override;
133#endif
134
joshualitta751c972015-11-20 13:37:32 -0800135 GrMaskFormat maskFormat() const {
136 switch (fMaskType) {
Michael Ludwig136d8782020-11-03 11:04:16 -0500137 case MaskType::kLCDCoverage:
joshualitta751c972015-11-20 13:37:32 -0800138 return kA565_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500139 case MaskType::kColorBitmap:
joshualitta751c972015-11-20 13:37:32 -0800140 return kARGB_GrMaskFormat;
Michael Ludwig136d8782020-11-03 11:04:16 -0500141 case MaskType::kGrayscaleCoverage:
142 case MaskType::kAliasedDistanceField:
143 case MaskType::kGrayscaleDistanceField:
144 case MaskType::kLCDDistanceField:
145 case MaskType::kLCDBGRDistanceField:
joshualitta751c972015-11-20 13:37:32 -0800146 return kA8_GrMaskFormat;
147 }
Michael Ludwig136d8782020-11-03 11:04:16 -0500148 // SkUNREACHABLE;
149 return kA8_GrMaskFormat;
joshualitta751c972015-11-20 13:37:32 -0800150 }
151
152 bool usesDistanceFields() const {
Michael Ludwig136d8782020-11-03 11:04:16 -0500153 return MaskType::kAliasedDistanceField == fMaskType ||
154 MaskType::kGrayscaleDistanceField == fMaskType ||
155 MaskType::kLCDDistanceField == fMaskType ||
156 MaskType::kLCDBGRDistanceField == fMaskType;
joshualitta751c972015-11-20 13:37:32 -0800157 }
158
159 bool isLCD() const {
Michael Ludwig136d8782020-11-03 11:04:16 -0500160 return MaskType::kLCDCoverage == fMaskType ||
161 MaskType::kLCDDistanceField == fMaskType ||
162 MaskType::kLCDBGRDistanceField == fMaskType;
joshualitta751c972015-11-20 13:37:32 -0800163 }
164
Herb Derby4513cdd2020-01-31 13:28:49 -0500165 inline void createDrawForGeneratedGlyphs(
166 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const;
joshualitta751c972015-11-20 13:37:32 -0800167
Brian Osmancf860852018-10-31 14:04:39 -0400168 const SkPMColor4f& color() const { SkASSERT(fGeoCount > 0); return fGeoData[0].fColor; }
Brian Salomon344ec422016-12-15 10:58:41 -0500169 bool usesLocalCoords() const { return fUsesLocalCoords; }
170 int numGlyphs() const { return fNumGlyphs; }
joshualitta751c972015-11-20 13:37:32 -0800171
Herb Derbye25c3002020-10-27 15:57:27 -0400172 CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
joshualitta751c972015-11-20 13:37:32 -0800173
Robert Phillips841c9a52020-03-27 12:41:31 -0400174 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc*,
175 const GrShaderCaps&,
Greg Daniel9715b6c2019-12-10 15:03:10 -0500176 const GrSurfaceProxyView* views,
177 unsigned int numActiveViews) const;
joshualitta751c972015-11-20 13:37:32 -0800178
Herb Derby3c873af2020-04-29 15:56:07 -0400179 const MaskType fMaskType;
180 const bool fNeedsGlyphTransform;
181 const SkColor fLuminanceColor{0};
182 const bool fUseGammaCorrectDistanceTable{false};
183 // Distance field properties
184 const uint32_t fDFGPFlags;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400185 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
Jim Van Verthc8a65e32017-10-25 14:25:27 -0400186 int fGeoDataAllocSize;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400187 GrProcessorSet fProcessors;
Herb Derby3c873af2020-04-29 15:56:07 -0400188 bool fUsesLocalCoords;
Brian Salomon44acb5b2017-07-18 19:59:24 -0400189 int fGeoCount;
190 int fNumGlyphs;
joshualitta751c972015-11-20 13:37:32 -0800191
John Stiles7571f9e2020-09-02 22:42:33 -0400192 using INHERITED = GrMeshDrawOp;
joshualitta751c972015-11-20 13:37:32 -0800193};
194
joshualitta751c972015-11-20 13:37:32 -0800195#endif