GrBitmapTextGeoProc.cpp revision e7492fe49c61915b70bde648b75f9b6fc60b4bef
1/* 2 * Copyright 2013 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#include "GrBitmapTextGeoProc.h" 9 10#include "GrTexture.h" 11#include "glsl/GrGLSLFragmentShaderBuilder.h" 12#include "glsl/GrGLSLGeometryProcessor.h" 13#include "glsl/GrGLSLProgramDataManager.h" 14#include "glsl/GrGLSLUniformHandler.h" 15#include "glsl/GrGLSLVarying.h" 16#include "glsl/GrGLSLVertexShaderBuilder.h" 17 18class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor { 19public: 20 GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL), fAtlasSize({0,0}) {} 21 22 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 23 const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>(); 24 25 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 26 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 27 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 28 29 // emit attributes 30 varyingHandler->emitAttributes(btgp); 31 32 const char* atlasSizeInvName; 33 fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, 34 kVec2f_GrSLType, 35 kHigh_GrSLPrecision, 36 "AtlasSizeInv", 37 &atlasSizeInvName); 38 39 GrGLSLVertToFrag v(kVec2f_GrSLType); 40 varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); 41 vertBuilder->codeAppendf("%s = float2(%s.x, %s.y) * %s;", v.vsOut(), 42 btgp.inTextureCoords()->fName, 43 btgp.inTextureCoords()->fName, 44 atlasSizeInvName); 45 46 GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; 47 // Setup pass through color 48 if (btgp.hasVertexColor()) { 49 varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor); 50 } else { 51 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, 52 &fColorUniform); 53 } 54 55 // Setup position 56 this->writeOutputPosition(vertBuilder, gpArgs, btgp.inPosition()->fName); 57 58 // emit transforms 59 this->emitTransforms(vertBuilder, 60 varyingHandler, 61 uniformHandler, 62 gpArgs->fPositionVar, 63 btgp.inPosition()->fName, 64 btgp.localMatrix(), 65 args.fFPCoordTransformHandler); 66 67 if (btgp.maskFormat() == kARGB_GrMaskFormat) { 68 fragBuilder->codeAppendf("%s = ", args.fOutputColor); 69 fragBuilder->appendTextureLookupAndModulate(args.fOutputColor, 70 args.fTexSamplers[0], 71 v.fsIn(), 72 kVec2f_GrSLType); 73 fragBuilder->codeAppend(";"); 74 fragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage); 75 } else { 76 fragBuilder->codeAppendf("%s = ", args.fOutputCoverage); 77 fragBuilder->appendTextureLookup(args.fTexSamplers[0], v.fsIn(), kVec2f_GrSLType); 78 fragBuilder->codeAppend(";"); 79 } 80 } 81 82 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, 83 FPCoordTransformIter&& transformIter) override { 84 const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>(); 85 if (btgp.color() != fColor && !btgp.hasVertexColor()) { 86 float c[4]; 87 GrColorToRGBAFloat(btgp.color(), c); 88 pdman.set4fv(fColorUniform, 1, c); 89 fColor = btgp.color(); 90 } 91 92 SkASSERT(btgp.numTextureSamplers() == 1); 93 GrTexture* atlas = btgp.textureSampler(0).peekTexture(); 94 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); 95 96 if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) { 97 pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height()); 98 fAtlasSize.set(atlas->width(), atlas->height()); 99 } 100 this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter); 101 } 102 103 static inline void GenKey(const GrGeometryProcessor& proc, 104 const GrShaderCaps&, 105 GrProcessorKeyBuilder* b) { 106 const GrBitmapTextGeoProc& btgp = proc.cast<GrBitmapTextGeoProc>(); 107 uint32_t key = 0; 108 key |= (btgp.usesLocalCoords() && btgp.localMatrix().hasPerspective()) ? 0x1 : 0x0; 109 key |= btgp.maskFormat() << 1; 110 b->add32(key); 111 } 112 113private: 114 GrColor fColor; 115 UniformHandle fColorUniform; 116 117 SkISize fAtlasSize; 118 UniformHandle fAtlasSizeInvUniform; 119 120 typedef GrGLSLGeometryProcessor INHERITED; 121}; 122 123/////////////////////////////////////////////////////////////////////////////// 124 125GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, sk_sp<GrTextureProxy> proxy, 126 const GrSamplerState& params, GrMaskFormat format, 127 const SkMatrix& localMatrix, bool usesLocalCoords) 128 : fColor(color) 129 , fLocalMatrix(localMatrix) 130 , fUsesLocalCoords(usesLocalCoords) 131 , fTextureSampler(std::move(proxy), params) 132 , fInColor(nullptr) 133 , fMaskFormat(format) { 134 this->initClassID<GrBitmapTextGeoProc>(); 135 fInPosition = 136 &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); 137 138 bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat || 139 kA565_GrMaskFormat == fMaskFormat; 140 if (hasVertexColor) { 141 fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); 142 } 143 144 fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType, 145 kHigh_GrSLPrecision); 146 this->addTextureSampler(&fTextureSampler); 147} 148 149void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps, 150 GrProcessorKeyBuilder* b) const { 151 GrGLBitmapTextGeoProc::GenKey(*this, caps, b); 152} 153 154GrGLSLPrimitiveProcessor* GrBitmapTextGeoProc::createGLSLInstance(const GrShaderCaps& caps) const { 155 return new GrGLBitmapTextGeoProc(); 156} 157 158/////////////////////////////////////////////////////////////////////////////// 159 160GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc); 161 162#if GR_TEST_UTILS 163 164sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) { 165 int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 166 : GrProcessorUnitTest::kAlphaTextureIdx; 167 sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx); 168 169 GrSamplerState::WrapMode wrapModes[2]; 170 GrTest::TestWrapModes(d->fRandom, wrapModes); 171 GrSamplerState samplerState(wrapModes, d->fRandom->nextBool() 172 ? GrSamplerState::Filter::kBilerp 173 : GrSamplerState::Filter::kNearest); 174 175 GrMaskFormat format = kARGB_GrMaskFormat; // init to avoid warning 176 switch (d->fRandom->nextULessThan(3)) { 177 case 0: 178 format = kA8_GrMaskFormat; 179 break; 180 case 1: 181 format = kA565_GrMaskFormat; 182 break; 183 case 2: 184 format = kARGB_GrMaskFormat; 185 break; 186 } 187 188 return GrBitmapTextGeoProc::Make(GrRandomColor(d->fRandom), std::move(proxy), samplerState, 189 format, GrTest::TestMatrix(d->fRandom), 190 d->fRandom->nextBool()); 191} 192#endif 193