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