• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "GrInvariantOutput.h"
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 
18 class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
19 public:
GrGLBitmapTextGeoProc()20     GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL) {}
21 
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)22     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
23         const GrBitmapTextGeoProc& cte = 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(cte);
31 
32         // compute numbers to be hardcoded to convert texture coordinates from int to float
33         SkASSERT(cte.numTextures() == 1);
34         SkDEBUGCODE(GrTexture* atlas = cte.textureAccess(0).getTexture());
35         SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
36 
37         GrGLSLVertToFrag v(kVec2f_GrSLType);
38         varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
39         vertBuilder->codeAppendf("%s = %s;", v.vsOut(),
40                                  cte.inTextureCoords()->fName);
41 
42         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
43         // Setup pass through color
44         if (!cte.colorIgnored()) {
45             if (cte.hasVertexColor()) {
46                 varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
47             } else {
48                 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
49                                         &fColorUniform);
50             }
51         }
52 
53         // Setup position
54         this->setupPosition(vertBuilder, gpArgs, cte.inPosition()->fName);
55 
56         // emit transforms
57         this->emitTransforms(vertBuilder,
58                              varyingHandler,
59                              uniformHandler,
60                              gpArgs->fPositionVar,
61                              cte.inPosition()->fName,
62                              cte.localMatrix(),
63                              args.fTransformsIn,
64                              args.fTransformsOut);
65 
66         if (cte.maskFormat() == kARGB_GrMaskFormat) {
67             fragBuilder->codeAppendf("%s = ", args.fOutputColor);
68             fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
69                                                         args.fSamplers[0],
70                                                         v.fsIn(),
71                                                         kVec2f_GrSLType);
72             fragBuilder->codeAppend(";");
73             fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
74         } else {
75             fragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
76             fragBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType);
77             fragBuilder->codeAppend(";");
78             if (cte.maskFormat() == kA565_GrMaskFormat) {
79                 // set alpha to be max of rgb coverage
80                 fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
81                                          args.fOutputCoverage, args.fOutputCoverage,
82                                          args.fOutputCoverage, args.fOutputCoverage);
83             }
84         }
85     }
86 
setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor & gp)87     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override {
88         const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
89         if (btgp.color() != fColor && !btgp.hasVertexColor()) {
90             float c[4];
91             GrColorToRGBAFloat(btgp.color(), c);
92             pdman.set4fv(fColorUniform, 1, c);
93             fColor = btgp.color();
94         }
95     }
96 
setTransformData(const GrPrimitiveProcessor & primProc,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)97     void setTransformData(const GrPrimitiveProcessor& primProc,
98                           const GrGLSLProgramDataManager& pdman,
99                           int index,
100                           const SkTArray<const GrCoordTransform*, true>& transforms) override {
101         this->setTransformDataHelper<GrBitmapTextGeoProc>(primProc, pdman, index, transforms);
102     }
103 
GenKey(const GrGeometryProcessor & proc,const GrGLSLCaps &,GrProcessorKeyBuilder * b)104     static inline void GenKey(const GrGeometryProcessor& proc,
105                               const GrGLSLCaps&,
106                               GrProcessorKeyBuilder* b) {
107         const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>();
108         uint32_t key = 0;
109         key |= gp.usesLocalCoords() && gp.localMatrix().hasPerspective() ? 0x1 : 0x0;
110         key |= gp.colorIgnored() ? 0x2 : 0x0;
111         key |= gp.maskFormat() << 3;
112         b->add32(key);
113 
114         // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
115         SkASSERT(gp.numTextures() == 1);
116         GrTexture* atlas = gp.textureAccess(0).getTexture();
117         SkASSERT(atlas);
118         b->add32(atlas->width());
119         b->add32(atlas->height());
120     }
121 
122 private:
123     GrColor fColor;
124     UniformHandle fColorUniform;
125 
126     typedef GrGLSLGeometryProcessor INHERITED;
127 };
128 
129 ///////////////////////////////////////////////////////////////////////////////
130 
GrBitmapTextGeoProc(GrColor color,GrTexture * texture,const GrTextureParams & params,GrMaskFormat format,const SkMatrix & localMatrix,bool usesLocalCoords)131 GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture,
132                                          const GrTextureParams& params, GrMaskFormat format,
133                                          const SkMatrix& localMatrix, bool usesLocalCoords)
134     : fColor(color)
135     , fLocalMatrix(localMatrix)
136     , fUsesLocalCoords(usesLocalCoords)
137     , fTextureAccess(texture, params)
138     , fInColor(nullptr)
139     , fMaskFormat(format) {
140     this->initClassID<GrBitmapTextGeoProc>();
141     fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
142 
143     bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
144                           kA565_GrMaskFormat == fMaskFormat;
145     if (hasVertexColor) {
146         fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
147     }
148     fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
149                                                         kVec2us_GrVertexAttribType,
150                                                         kHigh_GrSLPrecision));
151     this->addTextureAccess(&fTextureAccess);
152 }
153 
getGLSLProcessorKey(const GrGLSLCaps & caps,GrProcessorKeyBuilder * b) const154 void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrGLSLCaps& caps,
155                                               GrProcessorKeyBuilder* b) const {
156     GrGLBitmapTextGeoProc::GenKey(*this, caps, b);
157 }
158 
createGLSLInstance(const GrGLSLCaps & caps) const159 GrGLSLPrimitiveProcessor* GrBitmapTextGeoProc::createGLSLInstance(const GrGLSLCaps& caps) const {
160     return new GrGLBitmapTextGeoProc();
161 }
162 
163 ///////////////////////////////////////////////////////////////////////////////
164 
165 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
166 
TestCreate(GrProcessorTestData * d)167 const GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
168     int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
169                                           GrProcessorUnitTest::kAlphaTextureIdx;
170     static const SkShader::TileMode kTileModes[] = {
171         SkShader::kClamp_TileMode,
172         SkShader::kRepeat_TileMode,
173         SkShader::kMirror_TileMode,
174     };
175     SkShader::TileMode tileModes[] = {
176         kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
177         kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
178     };
179     GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
180                                                            GrTextureParams::kNone_FilterMode);
181 
182     GrMaskFormat format;
183     switch (d->fRandom->nextULessThan(3)) {
184         case 0:
185             format = kA8_GrMaskFormat;
186             break;
187         case 1:
188             format = kA565_GrMaskFormat;
189             break;
190         case 2:
191             format = kARGB_GrMaskFormat;
192             break;
193     }
194 
195     return GrBitmapTextGeoProc::Create(GrRandomColor(d->fRandom), d->fTextures[texIdx], params,
196                                        format, GrTest::TestMatrix(d->fRandom),
197                                        d->fRandom->nextBool());
198 }
199