• 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 "src/gpu/effects/GrBitmapTextGeoProc.h"
9 
10 #include "src/gpu/GrCaps.h"
11 #include "src/gpu/GrShaderCaps.h"
12 #include "src/gpu/GrTexture.h"
13 #include "src/gpu/effects/GrAtlasedShaderHelpers.h"
14 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
15 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
16 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
17 #include "src/gpu/glsl/GrGLSLVarying.h"
18 #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
19 
20 class GrBitmapTextGeoProc::Impl : public ProgramImpl {
21 public:
setData(const GrGLSLProgramDataManager & pdman,const GrShaderCaps & shaderCaps,const GrGeometryProcessor & geomProc)22     void setData(const GrGLSLProgramDataManager& pdman,
23                  const GrShaderCaps& shaderCaps,
24                  const GrGeometryProcessor& geomProc) override {
25         const GrBitmapTextGeoProc& btgp = geomProc.cast<GrBitmapTextGeoProc>();
26         if (btgp.fColor != fColor && !btgp.hasVertexColor()) {
27             pdman.set4fv(fColorUniform, 1, btgp.fColor.vec());
28             fColor = btgp.fColor;
29         }
30 
31         const SkISize& atlasDimensions = btgp.fAtlasDimensions;
32         SkASSERT(SkIsPow2(atlasDimensions.fWidth) && SkIsPow2(atlasDimensions.fHeight));
33 
34         if (fAtlasDimensions != atlasDimensions) {
35             pdman.set2f(fAtlasDimensionsInvUniform,
36                         1.0f / atlasDimensions.fWidth,
37                         1.0f / atlasDimensions.fHeight);
38             fAtlasDimensions = atlasDimensions;
39         }
40 
41         SetTransform(pdman, shaderCaps, fLocalMatrixUniform, btgp.fLocalMatrix, &fLocalMatrix);
42     }
43 
44 private:
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)45     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
46         const GrBitmapTextGeoProc& btgp = args.fGeomProc.cast<GrBitmapTextGeoProc>();
47 
48         GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
49         GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
50         GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
51 
52         // emit attributes
53         varyingHandler->emitAttributes(btgp);
54 
55         const char* atlasDimensionsInvName;
56         fAtlasDimensionsInvUniform = uniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
57                 kFloat2_GrSLType, "AtlasSizeInv", &atlasDimensionsInvName);
58 
59         GrGLSLVarying uv, texIdx;
60         append_index_uv_varyings(args,
61                                  btgp.numTextureSamplers(),
62                                  btgp.fInTextureCoords.name(),
63                                  atlasDimensionsInvName,
64                                  &uv,
65                                  &texIdx,
66                                  nullptr);
67 
68         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
69         // Setup pass through color
70         fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
71         if (btgp.hasVertexColor()) {
72             varyingHandler->addPassThroughAttribute(btgp.fInColor.asShaderVar(), args.fOutputColor);
73         } else {
74             this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
75                                     &fColorUniform);
76         }
77 
78         // Setup position
79         gpArgs->fPositionVar = btgp.fInPosition.asShaderVar();
80         WriteLocalCoord(vertBuilder,
81                         uniformHandler,
82                         *args.fShaderCaps,
83                         gpArgs,
84                         btgp.fInPosition.asShaderVar(),
85                         btgp.fLocalMatrix,
86                         &fLocalMatrixUniform);
87 
88         fragBuilder->codeAppend("half4 texColor;");
89         append_multitexture_lookup(args, btgp.numTextureSamplers(),
90                                    texIdx, uv.fsIn(), "texColor");
91 
92         if (btgp.fMaskFormat == kARGB_GrMaskFormat) {
93             // modulate by color
94             fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor);
95             fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
96         } else {
97             fragBuilder->codeAppendf("half4 %s = texColor;", args.fOutputCoverage);
98         }
99     }
100 
101 private:
102     SkPMColor4f fColor           = SK_PMColor4fILLEGAL;
103     SkISize     fAtlasDimensions = {-1, -1};
104     SkMatrix    fLocalMatrix     = SkMatrix::InvalidMatrix();
105 
106     UniformHandle fColorUniform;
107     UniformHandle fAtlasDimensionsInvUniform;
108     UniformHandle fLocalMatrixUniform;
109 };
110 
111 ///////////////////////////////////////////////////////////////////////////////
112 
GrBitmapTextGeoProc(const GrShaderCaps & caps,const SkPMColor4f & color,bool wideColor,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,GrMaskFormat format,const SkMatrix & localMatrix,bool usesW)113 GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps,
114                                          const SkPMColor4f& color,
115                                          bool wideColor,
116                                          const GrSurfaceProxyView* views,
117                                          int numActiveViews,
118                                          GrSamplerState params,
119                                          GrMaskFormat format,
120                                          const SkMatrix& localMatrix,
121                                          bool usesW)
122         : INHERITED(kGrBitmapTextGeoProc_ClassID)
123         , fColor(color)
124         , fLocalMatrix(localMatrix)
125         , fUsesW(usesW)
126         , fMaskFormat(format) {
127     SkASSERT(numActiveViews <= kMaxTextures);
128 
129     if (usesW) {
130         fInPosition = {"inPosition", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
131     } else {
132         fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
133     }
134 
135     bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
136                           kA565_GrMaskFormat == fMaskFormat;
137     if (hasVertexColor) {
138         fInColor = MakeColorAttribute("inColor", wideColor);
139     }
140 
141     fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
142                         caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType};
143     this->setVertexAttributes(&fInPosition, 3);
144 
145     if (numActiveViews) {
146         fAtlasDimensions = views[0].proxy()->dimensions();
147     }
148     for (int i = 0; i < numActiveViews; ++i) {
149         const GrSurfaceProxy* proxy = views[i].proxy();
150         SkASSERT(proxy);
151         SkASSERT(proxy->dimensions() == fAtlasDimensions);
152         fTextureSamplers[i].reset(params, proxy->backendFormat(), views[i].swizzle());
153     }
154     this->setTextureSamplerCnt(numActiveViews);
155 }
156 
addNewViews(const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params)157 void GrBitmapTextGeoProc::addNewViews(const GrSurfaceProxyView* views,
158                                       int numActiveViews,
159                                       GrSamplerState params) {
160     SkASSERT(numActiveViews <= kMaxTextures);
161     // Just to make sure we don't try to add too many proxies
162     numActiveViews = std::min(numActiveViews, kMaxTextures);
163 
164     if (!fTextureSamplers[0].isInitialized()) {
165         fAtlasDimensions = views[0].proxy()->dimensions();
166     }
167 
168     for (int i = 0; i < numActiveViews; ++i) {
169         const GrSurfaceProxy* proxy = views[i].proxy();
170         SkASSERT(proxy);
171         SkASSERT(proxy->dimensions() == fAtlasDimensions);
172 
173         if (!fTextureSamplers[i].isInitialized()) {
174             fTextureSamplers[i].reset(params, proxy->backendFormat(), views[i].swizzle());
175         }
176     }
177     this->setTextureSamplerCnt(numActiveViews);
178 }
179 
addToKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const180 void GrBitmapTextGeoProc::addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
181     b->addBool(fUsesW, "usesW");
182     static_assert(kLast_GrMaskFormat < (1u << 2));
183     b->addBits(2, fMaskFormat, "maskFormat");
184     b->addBits(ProgramImpl::kMatrixKeyBits,
185                ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix),
186                "localMatrixType");
187     b->add32(this->numTextureSamplers(), "numTextures");
188 }
189 
makeProgramImpl(const GrShaderCaps & caps) const190 std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrBitmapTextGeoProc::makeProgramImpl(
191         const GrShaderCaps& caps) const {
192     return std::make_unique<Impl>();
193 }
194 
195 ///////////////////////////////////////////////////////////////////////////////
196 
197 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
198 
199 #if GR_TEST_UTILS
200 
TestCreate(GrProcessorTestData * d)201 GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
202     auto [view, ct, at] = d->randomView();
203 
204     GrSamplerState::WrapMode wrapModes[2];
205     GrTest::TestWrapModes(d->fRandom, wrapModes);
206     GrSamplerState samplerState(wrapModes, d->fRandom->nextBool()
207                                                    ? GrSamplerState::Filter::kLinear
208                                                    : GrSamplerState::Filter::kNearest);
209 
210     GrMaskFormat format;
211     switch (ct) {
212         case GrColorType::kAlpha_8:
213             format = kA8_GrMaskFormat;
214             break;
215         case GrColorType::kBGR_565:
216             format = kA565_GrMaskFormat;
217             break;
218         case GrColorType::kRGBA_8888:
219         default:  // It doesn't really matter that color type and mask format agree.
220             format = kARGB_GrMaskFormat;
221             break;
222     }
223 
224     GrColor color = GrTest::RandomColor(d->fRandom);
225     bool wideColor = d->fRandom->nextBool();
226     SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
227     bool usesW = d->fRandom->nextBool();
228     return GrBitmapTextGeoProc::Make(d->allocator(), *d->caps()->shaderCaps(),
229                                      SkPMColor4f::FromBytes_RGBA(color),
230                                      wideColor,
231                                      &view, 1, samplerState, format,
232                                      localMatrix, usesW);
233 }
234 #endif
235