1 /* 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 8 #ifndef GrAtlasTextOp_DEFINED 9 #define GrAtlasTextOp_DEFINED 10 11 #include "src/gpu/ops/GrMeshDrawOp.h" 12 #include "src/gpu/text/GrDistanceFieldAdjustTable.h" 13 #include "src/gpu/text/GrTextBlob.h" 14 15 class GrRecordingContext; 16 class SkAtlasTextTarget; 17 18 class GrAtlasTextOp final : public GrMeshDrawOp { 19 public: 20 DEFINE_OP_CLASS_ID 21 ~GrAtlasTextOp()22 ~GrAtlasTextOp() override { 23 for (int i = 0; i < fGeoCount; i++) { 24 fGeoData[i].fBlob->unref(); 25 } 26 } 27 28 static const int kVerticesPerGlyph = GrTextBlob::kVerticesPerGlyph; 29 static const int kIndicesPerGlyph = 6; 30 31 struct Geometry { 32 SkMatrix fDrawMatrix; 33 SkIRect fClipRect; 34 GrTextBlob* fBlob; 35 SkPoint fDrawOrigin; 36 GrTextBlob::SubRun* fSubRunPtr; 37 SkPMColor4f fColor; 38 }; 39 40 static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrRecordingContext*, 41 GrPaint&&, 42 GrMaskFormat, 43 int glyphCount, 44 bool needsTransform); 45 46 static std::unique_ptr<GrAtlasTextOp> MakeDistanceField( 47 GrRecordingContext*, 48 GrPaint&&, 49 int glyphCount, 50 const GrDistanceFieldAdjustTable*, 51 bool useGammaCorrectDistanceTable, 52 SkColor luminanceColor, 53 const SkSurfaceProps&, 54 bool isAntiAliased, 55 bool useLCD); 56 57 // To avoid even the initial copy of the struct, we have a getter for the first item which 58 // is used to seed the op with its initial geometry. After seeding, the client should call 59 // init() so the op can initialize itself geometry()60 Geometry& geometry() { return fGeoData[0]; } 61 62 /** Called after this->geometry() has been configured. */ 63 void init(); 64 name()65 const char* name() const override { return "AtlasTextOp"; } 66 67 void visitProxies(const VisitProxyFunc& func) const override; 68 69 #ifdef SK_DEBUG 70 SkString dumpInfo() const override; 71 #endif 72 73 FixedFunctionFlags fixedFunctionFlags() const override; 74 75 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, 76 bool hasMixedSampledCoverage, GrClampType) override; 77 78 enum MaskType { 79 kGrayscaleCoverageMask_MaskType, 80 kLCDCoverageMask_MaskType, 81 kColorBitmapMask_MaskType, 82 kAliasedDistanceField_MaskType, 83 kGrayscaleDistanceField_MaskType, 84 kLCDDistanceField_MaskType, 85 kLCDBGRDistanceField_MaskType, 86 }; 87 maskType()88 MaskType maskType() const { return fMaskType; } 89 90 void finalizeForTextTarget(uint32_t color, const GrCaps&); 91 void executeForTextTarget(SkAtlasTextTarget*); 92 93 private: 94 friend class GrOpMemoryPool; // for ctor 95 96 // The minimum number of Geometry we will try to allocate. 97 static constexpr auto kMinGeometryAllocated = 12; 98 GrAtlasTextOp(GrPaint && paint)99 GrAtlasTextOp(GrPaint&& paint) 100 : INHERITED(ClassID()) 101 , fGeoDataAllocSize(kMinGeometryAllocated) 102 , fProcessors(std::move(paint)) {} 103 104 struct FlushInfo { 105 sk_sp<const GrBuffer> fVertexBuffer; 106 sk_sp<const GrBuffer> fIndexBuffer; 107 GrGeometryProcessor* fGeometryProcessor; 108 GrPipeline::FixedDynamicState* fFixedDynamicState; 109 int fGlyphsToFlush = 0; 110 int fVertexOffset = 0; 111 int fNumDraws = 0; 112 }; 113 114 void onPrepareDraws(Target*) override; 115 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 116 maskFormat()117 GrMaskFormat maskFormat() const { 118 switch (fMaskType) { 119 case kLCDCoverageMask_MaskType: 120 return kA565_GrMaskFormat; 121 case kColorBitmapMask_MaskType: 122 return kARGB_GrMaskFormat; 123 case kGrayscaleCoverageMask_MaskType: 124 case kAliasedDistanceField_MaskType: 125 case kGrayscaleDistanceField_MaskType: 126 case kLCDDistanceField_MaskType: 127 case kLCDBGRDistanceField_MaskType: 128 return kA8_GrMaskFormat; 129 } 130 return kA8_GrMaskFormat; // suppress warning 131 } 132 usesDistanceFields()133 bool usesDistanceFields() const { 134 return kAliasedDistanceField_MaskType == fMaskType || 135 kGrayscaleDistanceField_MaskType == fMaskType || 136 kLCDDistanceField_MaskType == fMaskType || 137 kLCDBGRDistanceField_MaskType == fMaskType; 138 } 139 isLCD()140 bool isLCD() const { 141 return kLCDCoverageMask_MaskType == fMaskType || 142 kLCDDistanceField_MaskType == fMaskType || 143 kLCDBGRDistanceField_MaskType == fMaskType; 144 } 145 146 inline void createDrawForGeneratedGlyphs( 147 GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const; 148 color()149 const SkPMColor4f& color() const { SkASSERT(fGeoCount > 0); return fGeoData[0].fColor; } usesLocalCoords()150 bool usesLocalCoords() const { return fUsesLocalCoords; } numGlyphs()151 int numGlyphs() const { return fNumGlyphs; } 152 153 CombineResult onCombineIfPossible(GrOp* t, GrRecordingContext::Arenas*, 154 const GrCaps& caps) override; 155 156 GrGeometryProcessor* setupDfProcessor(SkArenaAlloc* arena, 157 const GrShaderCaps& caps, 158 const GrSurfaceProxyView* views, 159 unsigned int numActiveViews) const; 160 161 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData; 162 int fGeoDataAllocSize; 163 GrProcessorSet fProcessors; 164 struct { 165 uint32_t fUsesLocalCoords : 1; 166 uint32_t fUseGammaCorrectDistanceTable : 1; 167 uint32_t fNeedsGlyphTransform : 1; 168 }; 169 int fGeoCount; 170 int fNumGlyphs; 171 MaskType fMaskType; 172 // Distance field properties 173 sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable; 174 SkColor fLuminanceColor; 175 uint32_t fDFGPFlags = 0; 176 177 typedef GrMeshDrawOp INHERITED; 178 }; 179 180 #endif 181