• 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 
10 #include "GrAtlasedShaderHelpers.h"
11 #include "GrCaps.h"
12 #include "GrShaderCaps.h"
13 #include "GrTexture.h"
14 #include "glsl/GrGLSLFragmentShaderBuilder.h"
15 #include "glsl/GrGLSLGeometryProcessor.h"
16 #include "glsl/GrGLSLProgramDataManager.h"
17 #include "glsl/GrGLSLUniformHandler.h"
18 #include "glsl/GrGLSLVarying.h"
19 #include "glsl/GrGLSLVertexGeoBuilder.h"
20 
21 class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
22 public:
GrGLBitmapTextGeoProc()23     GrGLBitmapTextGeoProc() : fColor(SK_PMColor4fILLEGAL), fAtlasSize({0,0}) {}
24 
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)25     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
26         const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>();
27 
28         GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
29         GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
30         GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
31 
32         // emit attributes
33         varyingHandler->emitAttributes(btgp);
34 
35         const char* atlasSizeInvName;
36         fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
37                                                           kFloat2_GrSLType,
38                                                           kHigh_GrSLPrecision,
39                                                           "AtlasSizeInv",
40                                                           &atlasSizeInvName);
41 
42         GrGLSLVarying uv(kFloat2_GrSLType);
43         GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
44         GrGLSLVarying texIdx(texIdxType);
45         append_index_uv_varyings(args, btgp.inTextureCoords().name(), atlasSizeInvName, &uv,
46                                  &texIdx, nullptr);
47 
48         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
49         // Setup pass through color
50         if (btgp.hasVertexColor()) {
51             varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor);
52         } else {
53             this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
54                                     &fColorUniform);
55         }
56 
57         // Setup position
58         gpArgs->fPositionVar = btgp.inPosition().asShaderVar();
59 
60         // emit transforms
61         this->emitTransforms(vertBuilder,
62                              varyingHandler,
63                              uniformHandler,
64                              btgp.inPosition().asShaderVar(),
65                              btgp.localMatrix(),
66                              args.fFPCoordTransformHandler);
67 
68         fragBuilder->codeAppend("half4 texColor;");
69         append_multitexture_lookup(args, btgp.numTextureSamplers(),
70                                    texIdx, uv.fsIn(), "texColor");
71 
72         if (btgp.maskFormat() == kARGB_GrMaskFormat) {
73             // modulate by color
74             fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor);
75             fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
76         } else {
77             fragBuilder->codeAppendf("%s = texColor;", args.fOutputCoverage);
78         }
79     }
80 
setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor & gp,FPCoordTransformIter && transformIter)81     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
82                  FPCoordTransformIter&& transformIter) override {
83         const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
84         if (btgp.color() != fColor && !btgp.hasVertexColor()) {
85             pdman.set4fv(fColorUniform, 1, btgp.color().vec());
86             fColor = btgp.color();
87         }
88 
89         const SkISize& atlasSize = btgp.atlasSize();
90         SkASSERT(SkIsPow2(atlasSize.fWidth) && SkIsPow2(atlasSize.fHeight));
91 
92         if (fAtlasSize != atlasSize) {
93             pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlasSize.fWidth, 1.0f / atlasSize.fHeight);
94             fAtlasSize = atlasSize;
95         }
96         this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
97     }
98 
GenKey(const GrGeometryProcessor & proc,const GrShaderCaps &,GrProcessorKeyBuilder * b)99     static inline void GenKey(const GrGeometryProcessor& proc,
100                               const GrShaderCaps&,
101                               GrProcessorKeyBuilder* b) {
102         const GrBitmapTextGeoProc& btgp = proc.cast<GrBitmapTextGeoProc>();
103         uint32_t key = 0;
104         key |= btgp.usesW() ? 0x1 : 0x0;
105         key |= btgp.maskFormat() << 1;
106         b->add32(key);
107         b->add32(btgp.numTextureSamplers());
108     }
109 
110 private:
111     SkPMColor4f   fColor;
112     UniformHandle fColorUniform;
113 
114     SkISize       fAtlasSize;
115     UniformHandle fAtlasSizeInvUniform;
116 
117     typedef GrGLSLGeometryProcessor INHERITED;
118 };
119 
120 ///////////////////////////////////////////////////////////////////////////////
121 
GrBitmapTextGeoProc(const GrShaderCaps & caps,const SkPMColor4f & color,bool wideColor,const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params,GrMaskFormat format,const SkMatrix & localMatrix,bool usesW)122 GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps,
123                                          const SkPMColor4f& color,
124                                          bool wideColor,
125                                          const sk_sp<GrTextureProxy>* proxies,
126                                          int numActiveProxies,
127                                          const GrSamplerState& params, GrMaskFormat format,
128                                          const SkMatrix& localMatrix, bool usesW)
129         : INHERITED(kGrBitmapTextGeoProc_ClassID)
130         , fColor(color)
131         , fLocalMatrix(localMatrix)
132         , fUsesW(usesW)
133         , fMaskFormat(format) {
134     SkASSERT(numActiveProxies <= kMaxTextures);
135 
136     if (usesW) {
137         fInPosition = {"inPosition", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
138     } else {
139         fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
140     }
141 
142     bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
143                           kA565_GrMaskFormat == fMaskFormat;
144     if (hasVertexColor) {
145         fInColor = MakeColorAttribute("inColor", wideColor);
146     }
147 
148     fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
149                         caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType};
150     this->setVertexAttributes(&fInPosition, 3);
151 
152     if (numActiveProxies) {
153         fAtlasSize = proxies[0]->isize();
154     }
155     for (int i = 0; i < numActiveProxies; ++i) {
156         SkASSERT(proxies[i]);
157         SkASSERT(proxies[i]->isize() == fAtlasSize);
158         fTextureSamplers[i].reset(proxies[i]->textureType(), proxies[i]->config(), params);
159     }
160     this->setTextureSamplerCnt(numActiveProxies);
161 }
162 
addNewProxies(const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params)163 void GrBitmapTextGeoProc::addNewProxies(const sk_sp<GrTextureProxy>* proxies,
164                                         int numActiveProxies,
165                                         const GrSamplerState& params) {
166     SkASSERT(numActiveProxies <= kMaxTextures);
167 
168     if (!fTextureSamplers[0].isInitialized()) {
169         fAtlasSize = proxies[0]->isize();
170     }
171 
172     for (int i = 0; i < numActiveProxies; ++i) {
173         SkASSERT(proxies[i]);
174         SkASSERT(proxies[i]->isize() == fAtlasSize);
175 
176         if (!fTextureSamplers[i].isInitialized()) {
177             fTextureSamplers[i].reset(proxies[i]->textureType(), proxies[i]->config(), params);
178         }
179     }
180     this->setTextureSamplerCnt(numActiveProxies);
181 }
182 
getGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const183 void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
184                                               GrProcessorKeyBuilder* b) const {
185     GrGLBitmapTextGeoProc::GenKey(*this, caps, b);
186 }
187 
createGLSLInstance(const GrShaderCaps & caps) const188 GrGLSLPrimitiveProcessor* GrBitmapTextGeoProc::createGLSLInstance(const GrShaderCaps& caps) const {
189     return new GrGLBitmapTextGeoProc();
190 }
191 
192 ///////////////////////////////////////////////////////////////////////////////
193 
194 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
195 
196 #if GR_TEST_UTILS
197 
TestCreate(GrProcessorTestData * d)198 sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
199     int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
200                                         : GrProcessorUnitTest::kAlphaTextureIdx;
201     sk_sp<GrTextureProxy> proxies[kMaxTextures] = {
202         d->textureProxy(texIdx),
203         nullptr,
204         nullptr,
205         nullptr
206     };
207 
208     GrSamplerState::WrapMode wrapModes[2];
209     GrTest::TestWrapModes(d->fRandom, wrapModes);
210     GrSamplerState samplerState(wrapModes, d->fRandom->nextBool()
211                                                    ? GrSamplerState::Filter::kBilerp
212                                                    : GrSamplerState::Filter::kNearest);
213 
214     GrMaskFormat format = kARGB_GrMaskFormat; // init to avoid warning
215     switch (d->fRandom->nextULessThan(3)) {
216         case 0:
217             format = kA8_GrMaskFormat;
218             break;
219         case 1:
220             format = kA565_GrMaskFormat;
221             break;
222         case 2:
223             format = kARGB_GrMaskFormat;
224             break;
225     }
226 
227     return GrBitmapTextGeoProc::Make(*d->caps()->shaderCaps(),
228                                      SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
229                                      d->fRandom->nextBool(),
230                                      proxies, 1, samplerState, format,
231                                      GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
232 }
233 #endif
234