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