Line data Source code
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 "GrTexture.h"
11 : #include "glsl/GrGLSLFragmentShaderBuilder.h"
12 : #include "glsl/GrGLSLGeometryProcessor.h"
13 : #include "glsl/GrGLSLProgramDataManager.h"
14 : #include "glsl/GrGLSLUniformHandler.h"
15 : #include "glsl/GrGLSLVarying.h"
16 : #include "glsl/GrGLSLVertexShaderBuilder.h"
17 :
18 0 : class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
19 : public:
20 0 : GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL) {}
21 :
22 0 : void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
23 0 : const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
24 :
25 0 : GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
26 0 : GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
27 0 : GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
28 :
29 : // emit attributes
30 0 : varyingHandler->emitAttributes(cte);
31 :
32 : // compute numbers to be hardcoded to convert texture coordinates from int to float
33 0 : SkASSERT(cte.numTextureSamplers() == 1);
34 0 : SkDEBUGCODE(GrTexture* atlas = cte.textureSampler(0).texture());
35 0 : SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
36 :
37 0 : GrGLSLVertToFrag v(kVec2f_GrSLType);
38 0 : varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
39 0 : vertBuilder->codeAppendf("%s = %s;", v.vsOut(),
40 0 : cte.inTextureCoords()->fName);
41 :
42 0 : GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
43 : // Setup pass through color
44 0 : if (cte.hasVertexColor()) {
45 0 : varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
46 : } else {
47 0 : this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
48 0 : &fColorUniform);
49 : }
50 :
51 : // Setup position
52 0 : this->setupPosition(vertBuilder, gpArgs, cte.inPosition()->fName);
53 :
54 : // emit transforms
55 0 : this->emitTransforms(vertBuilder,
56 : varyingHandler,
57 : uniformHandler,
58 : gpArgs->fPositionVar,
59 0 : cte.inPosition()->fName,
60 : cte.localMatrix(),
61 0 : args.fFPCoordTransformHandler);
62 :
63 0 : if (cte.maskFormat() == kARGB_GrMaskFormat) {
64 0 : fragBuilder->codeAppendf("%s = ", args.fOutputColor);
65 0 : fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
66 0 : args.fTexSamplers[0],
67 : v.fsIn(),
68 0 : kVec2f_GrSLType);
69 0 : fragBuilder->codeAppend(";");
70 0 : fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
71 : } else {
72 0 : fragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
73 0 : fragBuilder->appendTextureLookup(args.fTexSamplers[0], v.fsIn(), kVec2f_GrSLType);
74 0 : fragBuilder->codeAppend(";");
75 0 : if (cte.maskFormat() == kA565_GrMaskFormat) {
76 : // set alpha to be max of rgb coverage
77 0 : fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
78 : args.fOutputCoverage, args.fOutputCoverage,
79 0 : args.fOutputCoverage, args.fOutputCoverage);
80 : }
81 : }
82 0 : }
83 :
84 0 : void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
85 : FPCoordTransformIter&& transformIter) override {
86 0 : const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
87 0 : if (btgp.color() != fColor && !btgp.hasVertexColor()) {
88 : float c[4];
89 0 : GrColorToRGBAFloat(btgp.color(), c);
90 0 : pdman.set4fv(fColorUniform, 1, c);
91 0 : fColor = btgp.color();
92 : }
93 0 : this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
94 0 : }
95 :
96 0 : static inline void GenKey(const GrGeometryProcessor& proc,
97 : const GrShaderCaps&,
98 : GrProcessorKeyBuilder* b) {
99 0 : const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>();
100 0 : uint32_t key = 0;
101 0 : key |= (gp.usesLocalCoords() && gp.localMatrix().hasPerspective()) ? 0x1 : 0x0;
102 0 : key |= gp.maskFormat() << 1;
103 0 : b->add32(key);
104 :
105 : // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
106 0 : SkASSERT(gp.numTextureSamplers() == 1);
107 0 : GrTexture* atlas = gp.textureSampler(0).texture();
108 0 : SkASSERT(atlas);
109 0 : b->add32(atlas->width());
110 0 : b->add32(atlas->height());
111 0 : }
112 :
113 : private:
114 : GrColor fColor;
115 : UniformHandle fColorUniform;
116 :
117 : typedef GrGLSLGeometryProcessor INHERITED;
118 : };
119 :
120 : ///////////////////////////////////////////////////////////////////////////////
121 :
122 0 : GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrResourceProvider* resourceProvider, GrColor color,
123 : sk_sp<GrTextureProxy> proxy,
124 : const GrSamplerParams& params, GrMaskFormat format,
125 0 : const SkMatrix& localMatrix, bool usesLocalCoords)
126 : : fColor(color)
127 : , fLocalMatrix(localMatrix)
128 : , fUsesLocalCoords(usesLocalCoords)
129 0 : , fTextureSampler(resourceProvider, std::move(proxy), params)
130 : , fInColor(nullptr)
131 0 : , fMaskFormat(format) {
132 0 : this->initClassID<GrBitmapTextGeoProc>();
133 0 : fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType);
134 :
135 0 : bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
136 0 : kA565_GrMaskFormat == fMaskFormat;
137 0 : if (hasVertexColor) {
138 0 : fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
139 : }
140 0 : fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType,
141 0 : kHigh_GrSLPrecision);
142 0 : this->addTextureSampler(&fTextureSampler);
143 0 : }
144 :
145 0 : void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
146 : GrProcessorKeyBuilder* b) const {
147 0 : GrGLBitmapTextGeoProc::GenKey(*this, caps, b);
148 0 : }
149 :
150 0 : GrGLSLPrimitiveProcessor* GrBitmapTextGeoProc::createGLSLInstance(const GrShaderCaps& caps) const {
151 0 : return new GrGLBitmapTextGeoProc();
152 : }
153 :
154 : ///////////////////////////////////////////////////////////////////////////////
155 :
156 : GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
157 :
158 : #if GR_TEST_UTILS
159 0 : sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
160 0 : int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
161 0 : : GrProcessorUnitTest::kAlphaTextureIdx;
162 0 : sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
163 :
164 : static const SkShader::TileMode kTileModes[] = {
165 : SkShader::kClamp_TileMode,
166 : SkShader::kRepeat_TileMode,
167 : SkShader::kMirror_TileMode,
168 : };
169 : SkShader::TileMode tileModes[] = {
170 0 : kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
171 0 : kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
172 0 : };
173 0 : GrSamplerParams params(tileModes, d->fRandom->nextBool() ? GrSamplerParams::kBilerp_FilterMode
174 0 : : GrSamplerParams::kNone_FilterMode);
175 :
176 0 : GrMaskFormat format = kARGB_GrMaskFormat; // init to avoid warning
177 0 : switch (d->fRandom->nextULessThan(3)) {
178 : case 0:
179 0 : format = kA8_GrMaskFormat;
180 0 : break;
181 : case 1:
182 0 : format = kA565_GrMaskFormat;
183 0 : break;
184 : case 2:
185 0 : format = kARGB_GrMaskFormat;
186 0 : break;
187 : }
188 :
189 : return GrBitmapTextGeoProc::Make(d->resourceProvider(), GrRandomColor(d->fRandom),
190 0 : std::move(proxy),
191 : params, format, GrTest::TestMatrix(d->fRandom),
192 0 : d->fRandom->nextBool());
193 : }
194 : #endif
|