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