OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrBitmapTextGeoProc.h" | 8 #include "GrBitmapTextGeoProc.h" |
9 #include "GrFontAtlasSizes.h" | 9 #include "GrFontAtlasSizes.h" |
10 #include "GrInvariantOutput.h" | 10 #include "GrInvariantOutput.h" |
11 #include "GrTexture.h" | 11 #include "GrTexture.h" |
12 #include "gl/GrGLProcessor.h" | 12 #include "gl/GrGLProcessor.h" |
13 #include "gl/GrGLSL.h" | 13 #include "gl/GrGLSL.h" |
14 #include "gl/GrGLTexture.h" | 14 #include "gl/GrGLTexture.h" |
15 #include "gl/GrGLGeometryProcessor.h" | 15 #include "gl/GrGLGeometryProcessor.h" |
16 #include "gl/builders/GrGLProgramBuilder.h" | 16 #include "gl/builders/GrGLProgramBuilder.h" |
17 | 17 |
| 18 struct BitmapTextBatchTracker { |
| 19 GrGPInput fInputColorType; |
| 20 GrColor fColor; |
| 21 bool fUsesLocalCoords; |
| 22 }; |
| 23 |
18 class GrGLBitmapTextGeoProc : public GrGLGeometryProcessor { | 24 class GrGLBitmapTextGeoProc : public GrGLGeometryProcessor { |
19 public: | 25 public: |
20 GrGLBitmapTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) | 26 GrGLBitmapTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) |
21 : fColor(GrColor_ILLEGAL) {} | 27 : fColor(GrColor_ILLEGAL) {} |
22 | 28 |
23 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 29 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
24 const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); | 30 const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); |
| 31 const BitmapTextBatchTracker& local = args.fBT.cast<BitmapTextBatchTrack
er>(); |
25 | 32 |
26 GrGLGPBuilder* pb = args.fPB; | 33 GrGLGPBuilder* pb = args.fPB; |
27 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); | 34 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); |
28 | 35 |
29 // emit attributes | 36 // emit attributes |
30 vsBuilder->emitAttributes(cte); | 37 vsBuilder->emitAttributes(cte); |
31 | 38 |
32 GrGLVertToFrag v(kVec2f_GrSLType); | 39 GrGLVertToFrag v(kVec2f_GrSLType); |
33 pb->addVarying("TextureCoords", &v); | 40 pb->addVarying("TextureCoords", &v); |
34 // this is only used with text, so our texture bounds always match the g
lyph atlas | 41 // this is only used with text, so our texture bounds always match the g
lyph atlas |
35 if (cte.maskFormat() == kA8_GrMaskFormat) { | 42 if (cte.maskFormat() == kA8_GrMaskFormat) { |
36 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ",
" | 43 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ",
" |
37 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut()
, | 44 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut()
, |
38 cte.inTextureCoords()->fName); | 45 cte.inTextureCoords()->fName); |
39 } else { | 46 } else { |
40 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", " | 47 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", " |
41 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut()
, | 48 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut()
, |
42 cte.inTextureCoords()->fName); | 49 cte.inTextureCoords()->fName); |
43 } | 50 } |
44 | 51 |
45 // Setup pass through color | 52 // Setup pass through color |
46 if (!cte.colorIgnored()) { | 53 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor
, cte.inColor(), |
47 if (cte.hasVertexColor()) { | 54 &fColorUniform); |
48 pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor); | |
49 } else { | |
50 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); | |
51 } | |
52 } | |
53 | 55 |
54 // Setup position | 56 // Setup position |
55 this->setupPosition(pb, gpArgs, cte.inPosition()->fName); | 57 this->setupPosition(pb, gpArgs, cte.inPosition()->fName); |
56 | 58 |
57 // emit transforms | 59 // emit transforms |
58 this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->f
Name, | 60 this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->f
Name, |
59 cte.localMatrix(), args.fTransformsIn, args.fTransf
ormsOut); | 61 cte.localMatrix(), args.fTransformsIn, args.fTransf
ormsOut); |
60 | 62 |
61 GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); | 63 GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); |
62 if (cte.maskFormat() == kARGB_GrMaskFormat) { | 64 if (cte.maskFormat() == kARGB_GrMaskFormat) { |
63 fsBuilder->codeAppendf("%s = ", args.fOutputColor); | 65 fsBuilder->codeAppendf("%s = ", args.fOutputColor); |
64 fsBuilder->appendTextureLookupAndModulate(args.fOutputColor, | 66 fsBuilder->appendTextureLookupAndModulate(args.fOutputColor, |
65 args.fSamplers[0], | 67 args.fSamplers[0], |
66 v.fsIn(), | 68 v.fsIn(), |
67 kVec2f_GrSLType); | 69 kVec2f_GrSLType); |
68 fsBuilder->codeAppend(";"); | 70 fsBuilder->codeAppend(";"); |
69 fsBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage); | 71 fsBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage); |
70 } else { | 72 } else { |
71 fsBuilder->codeAppendf("%s = ", args.fOutputCoverage); | 73 fsBuilder->codeAppendf("%s = ", args.fOutputCoverage); |
72 fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_G
rSLType); | 74 fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_G
rSLType); |
73 fsBuilder->codeAppend(";"); | 75 fsBuilder->codeAppend(";"); |
74 } | 76 } |
75 } | 77 } |
76 | 78 |
77 virtual void setData(const GrGLProgramDataManager& pdman, | 79 virtual void setData(const GrGLProgramDataManager& pdman, |
78 const GrPrimitiveProcessor& gp, | 80 const GrPrimitiveProcessor& gp, |
79 const GrBatchTracker& bt) override { | 81 const GrBatchTracker& bt) override { |
80 const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>(); | 82 const BitmapTextBatchTracker& local = bt.cast<BitmapTextBatchTracker>(); |
81 if (btgp.color() != fColor && !btgp.hasVertexColor()) { | 83 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo
r) { |
82 GrGLfloat c[4]; | 84 GrGLfloat c[4]; |
83 GrColorToRGBAFloat(btgp.color(), c); | 85 GrColorToRGBAFloat(local.fColor, c); |
84 pdman.set4fv(fColorUniform, 1, c); | 86 pdman.set4fv(fColorUniform, 1, c); |
85 fColor = btgp.color(); | 87 fColor = local.fColor; |
86 } | 88 } |
87 } | 89 } |
88 | 90 |
89 void setTransformData(const GrPrimitiveProcessor& primProc, | 91 void setTransformData(const GrPrimitiveProcessor& primProc, |
90 const GrGLProgramDataManager& pdman, | 92 const GrGLProgramDataManager& pdman, |
91 int index, | 93 int index, |
92 const SkTArray<const GrCoordTransform*, true>& transfo
rms) override { | 94 const SkTArray<const GrCoordTransform*, true>& transfo
rms) override { |
93 this->setTransformDataHelper<GrBitmapTextGeoProc>(primProc, pdman, index
, transforms); | 95 this->setTransformDataHelper<GrBitmapTextGeoProc>(primProc, pdman, index
, transforms); |
94 } | 96 } |
95 | 97 |
96 static inline void GenKey(const GrGeometryProcessor& proc, | 98 static inline void GenKey(const GrGeometryProcessor& proc, |
97 const GrBatchTracker& bt, | 99 const GrBatchTracker& bt, |
98 const GrGLSLCaps&, | 100 const GrGLSLCaps&, |
99 GrProcessorKeyBuilder* b) { | 101 GrProcessorKeyBuilder* b) { |
| 102 const BitmapTextBatchTracker& local = bt.cast<BitmapTextBatchTracker>(); |
| 103 // We have to put the optional vertex attribute as part of the key. See
the comment |
| 104 // on addVertexAttrib. |
| 105 // TODO When we have deferred geometry we can fix this |
100 const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>(); | 106 const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>(); |
101 uint32_t key = 0; | 107 uint32_t key = 0; |
102 key |= gp.usesLocalCoords() && gp.localMatrix().hasPerspective() ? 0x1 :
0x0; | 108 key |= SkToBool(gp.inColor()) ? 0x1 : 0x0; |
103 key |= gp.colorIgnored() ? 0x2 : 0x0; | 109 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x2
: 0x0; |
104 key |= gp.maskFormat() << 3; | 110 key |= gp.maskFormat() == kARGB_GrMaskFormat ? 0x4 : 0x0; |
105 b->add32(key); | 111 b->add32(local.fInputColorType << 16 | key); |
106 } | 112 } |
107 | 113 |
108 private: | 114 private: |
109 GrColor fColor; | 115 GrColor fColor; |
110 UniformHandle fColorUniform; | 116 UniformHandle fColorUniform; |
111 | 117 |
112 typedef GrGLGeometryProcessor INHERITED; | 118 typedef GrGLGeometryProcessor INHERITED; |
113 }; | 119 }; |
114 | 120 |
115 /////////////////////////////////////////////////////////////////////////////// | 121 /////////////////////////////////////////////////////////////////////////////// |
116 | 122 |
117 GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture, | 123 GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture, |
118 const GrTextureParams& params, GrMaskFo
rmat format, | 124 const GrTextureParams& params, GrMaskFo
rmat format, |
119 const SkMatrix& localMatrix, bool usesL
ocalCoords) | 125 const SkMatrix& localMatrix) |
120 : fColor(color) | 126 : fColor(color) |
121 , fLocalMatrix(localMatrix) | 127 , fLocalMatrix(localMatrix) |
122 , fUsesLocalCoords(usesLocalCoords) | |
123 , fTextureAccess(texture, params) | 128 , fTextureAccess(texture, params) |
124 , fInColor(NULL) | 129 , fInColor(NULL) |
125 , fMaskFormat(format) { | 130 , fMaskFormat(format) { |
126 this->initClassID<GrBitmapTextGeoProc>(); | 131 this->initClassID<GrBitmapTextGeoProc>(); |
127 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); | 132 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); |
128 | 133 |
129 // TODO we could think about removing this attribute if color is ignored, bu
t unfortunately | |
130 // we don't do text positioning in batch, so we can't quite do that yet. | |
131 bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat; | 134 bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat; |
132 if (hasVertexColor) { | 135 if (hasVertexColor) { |
133 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexA
ttribType)); | 136 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexA
ttribType)); |
134 } | 137 } |
135 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", | 138 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", |
136 kVec2s_GrVertexAttribTyp
e)); | 139 kVec2s_GrVertexAttribTyp
e)); |
137 this->addTextureAccess(&fTextureAccess); | 140 this->addTextureAccess(&fTextureAccess); |
138 } | 141 } |
139 | 142 |
140 void GrBitmapTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, | 143 void GrBitmapTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, |
141 const GrGLSLCaps& caps, | 144 const GrGLSLCaps& caps, |
142 GrProcessorKeyBuilder* b) const { | 145 GrProcessorKeyBuilder* b) const { |
143 GrGLBitmapTextGeoProc::GenKey(*this, bt, caps, b); | 146 GrGLBitmapTextGeoProc::GenKey(*this, bt, caps, b); |
144 } | 147 } |
145 | 148 |
146 GrGLPrimitiveProcessor* | 149 GrGLPrimitiveProcessor* |
147 GrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt, | 150 GrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt, |
148 const GrGLSLCaps& caps) const { | 151 const GrGLSLCaps& caps) const { |
149 return SkNEW_ARGS(GrGLBitmapTextGeoProc, (*this, bt)); | 152 return SkNEW_ARGS(GrGLBitmapTextGeoProc, (*this, bt)); |
150 } | 153 } |
151 | 154 |
| 155 void GrBitmapTextGeoProc::initBatchTracker(GrBatchTracker* bt, const GrPipelineI
nfo& init) const { |
| 156 BitmapTextBatchTracker* local = bt->cast<BitmapTextBatchTracker>(); |
| 157 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in
it, |
| 158 SkToBool(fInColor)); |
| 159 local->fUsesLocalCoords = init.fUsesLocalCoords; |
| 160 } |
| 161 |
152 /////////////////////////////////////////////////////////////////////////////// | 162 /////////////////////////////////////////////////////////////////////////////// |
153 | 163 |
154 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc); | 164 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc); |
155 | 165 |
156 GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random, | 166 GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random, |
157 GrContext*, | 167 GrContext*, |
158 const GrDrawTargetCaps&, | 168 const GrDrawTargetCaps&, |
159 GrTexture* textures[]) { | 169 GrTexture* textures[]) { |
160 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : | 170 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
161 GrProcessorUnitTest::kAlphaTextureIdx; | 171 GrProcessorUnitTest::kAlphaTextureIdx; |
(...skipping 18 matching lines...) Expand all Loading... |
180 break; | 190 break; |
181 case 1: | 191 case 1: |
182 format = kA565_GrMaskFormat; | 192 format = kA565_GrMaskFormat; |
183 break; | 193 break; |
184 case 2: | 194 case 2: |
185 format = kARGB_GrMaskFormat; | 195 format = kARGB_GrMaskFormat; |
186 break; | 196 break; |
187 } | 197 } |
188 | 198 |
189 return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx],
params, | 199 return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx],
params, |
190 format, GrTest::TestMatrix(random), rando
m->nextBool()); | 200 format, GrTest::TestMatrix(random)); |
191 } | 201 } |
OLD | NEW |