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 "ops/GrMeshDrawOp.h" 12 #include "text/GrTextBlob.h" 13 #include "text/GrDistanceFieldAdjustTable.h" 14 15 class SkAtlasTextTarget; 16 class GrContext; 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(GrContext* context, 44 GrPaint&& paint, 45 GrMaskFormat maskFormat, 46 int glyphCount, 47 bool needsTransform); 48 49 static std::unique_ptr<GrAtlasTextOp> MakeDistanceField( 50 GrContext* context, 51 GrPaint&& paint, 52 int glyphCount, 53 const GrDistanceFieldAdjustTable* distanceAdjustTable, 54 bool useGammaCorrectDistanceTable, 55 SkColor luminanceColor, 56 const SkSurfaceProps& props, 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, VisitorType) 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& caps, const GrAppliedClip* clip) override; 79 80 enum MaskType { 81 kGrayscaleCoverageMask_MaskType, 82 kLCDCoverageMask_MaskType, 83 kColorBitmapMask_MaskType, 84 kAliasedDistanceField_MaskType, 85 kGrayscaleDistanceField_MaskType, 86 kLCDDistanceField_MaskType, 87 kLCDBGRDistanceField_MaskType, 88 }; 89 maskType()90 MaskType maskType() const { return fMaskType; } 91 92 void finalizeForTextTarget(uint32_t color, const GrCaps&); 93 void executeForTextTarget(SkAtlasTextTarget*); 94 95 private: 96 friend class GrOpMemoryPool; // for ctor 97 98 // The minimum number of Geometry we will try to allocate. 99 static constexpr auto kMinGeometryAllocated = 12; 100 GrAtlasTextOp(GrPaint && paint)101 GrAtlasTextOp(GrPaint&& paint) 102 : INHERITED(ClassID()) 103 , fGeoDataAllocSize(kMinGeometryAllocated) 104 , fProcessors(std::move(paint)) {} 105 106 struct FlushInfo { 107 sk_sp<const GrBuffer> fVertexBuffer; 108 sk_sp<const GrBuffer> fIndexBuffer; 109 sk_sp<GrGeometryProcessor> fGeometryProcessor; 110 const GrPipeline* fPipeline; 111 GrPipeline::FixedDynamicState* fFixedDynamicState; 112 int fGlyphsToFlush; 113 int fVertexOffset; 114 }; 115 116 void onPrepareDraws(Target*) override; 117 maskFormat()118 GrMaskFormat maskFormat() const { 119 switch (fMaskType) { 120 case kLCDCoverageMask_MaskType: 121 return kA565_GrMaskFormat; 122 case kColorBitmapMask_MaskType: 123 return kARGB_GrMaskFormat; 124 case kGrayscaleCoverageMask_MaskType: 125 case kAliasedDistanceField_MaskType: 126 case kGrayscaleDistanceField_MaskType: 127 case kLCDDistanceField_MaskType: 128 case kLCDBGRDistanceField_MaskType: 129 return kA8_GrMaskFormat; 130 } 131 return kA8_GrMaskFormat; // suppress warning 132 } 133 usesDistanceFields()134 bool usesDistanceFields() const { 135 return kAliasedDistanceField_MaskType == fMaskType || 136 kGrayscaleDistanceField_MaskType == fMaskType || 137 kLCDDistanceField_MaskType == fMaskType || 138 kLCDBGRDistanceField_MaskType == fMaskType; 139 } 140 isLCD()141 bool isLCD() const { 142 return kLCDCoverageMask_MaskType == fMaskType || 143 kLCDDistanceField_MaskType == fMaskType || 144 kLCDBGRDistanceField_MaskType == fMaskType; 145 } 146 147 inline void flush(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, const GrCaps& caps) override; 154 155 sk_sp<GrGeometryProcessor> setupDfProcessor(const GrShaderCaps& caps, 156 const sk_sp<GrTextureProxy>* proxies, 157 unsigned int numActiveProxies) const; 158 159 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData; 160 int fGeoDataAllocSize; 161 GrProcessorSet fProcessors; 162 struct { 163 uint32_t fUsesLocalCoords : 1; 164 uint32_t fUseGammaCorrectDistanceTable : 1; 165 uint32_t fNeedsGlyphTransform : 1; 166 }; 167 int fGeoCount; 168 int fNumGlyphs; 169 MaskType fMaskType; 170 // Distance field properties 171 sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable; 172 SkColor fLuminanceColor; 173 uint32_t fDFGPFlags = 0; 174 175 typedef GrMeshDrawOp INHERITED; 176 }; 177 178 #endif 179