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