OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
9 | 9 |
10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 : fGpu(gpu) | 41 : fGpu(gpu) |
42 , fUniformManager(gpu) | 42 , fUniformManager(gpu) |
43 , fHasVertexShader(false) | 43 , fHasVertexShader(false) |
44 , fNumTexCoordSets(0) { | 44 , fNumTexCoordSets(0) { |
45 fDesc = desc; | 45 fDesc = desc; |
46 fProgramID = 0; | 46 fProgramID = 0; |
47 | 47 |
48 fDstCopyTexUnit = -1; | 48 fDstCopyTexUnit = -1; |
49 | 49 |
50 fColor = GrColor_ILLEGAL; | 50 fColor = GrColor_ILLEGAL; |
51 fColorFilterColor = GrColor_ILLEGAL; | |
52 | 51 |
53 if (fDesc.getHeader().fHasVertexCode || | 52 if (fDesc.getHeader().fHasVertexCode || |
54 !fGpu->glCaps().fixedFunctionSupport() || | 53 !fGpu->glCaps().fixedFunctionSupport() || |
55 !fGpu->glCaps().pathStencilingSupport()) { | 54 !fGpu->glCaps().pathStencilingSupport()) { |
56 | 55 |
57 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); | 56 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); |
58 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { | 57 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { |
59 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); | 58 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); |
60 fHasVertexShader = true; | 59 fHasVertexShader = true; |
61 } | 60 } |
(...skipping 30 matching lines...) Expand all Loading... |
92 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: | 91 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: |
93 // We should only have set this if the blend was specified as (1, 0) | 92 // We should only have set this if the blend was specified as (1, 0) |
94 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); | 93 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); |
95 break; | 94 break; |
96 default: | 95 default: |
97 GrCrash("Unexpected coverage output"); | 96 GrCrash("Unexpected coverage output"); |
98 break; | 97 break; |
99 } | 98 } |
100 } | 99 } |
101 | 100 |
102 namespace { | |
103 // given two blend coefficients determine whether the src | |
104 // and/or dst computation can be omitted. | |
105 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, | |
106 SkXfermode::Coeff dstCoeff, | |
107 bool* needSrcValue, | |
108 bool* needDstValue) { | |
109 if (SkXfermode::kZero_Coeff == srcCoeff) { | |
110 switch (dstCoeff) { | |
111 // these all read the src | |
112 case SkXfermode::kSC_Coeff: | |
113 case SkXfermode::kISC_Coeff: | |
114 case SkXfermode::kSA_Coeff: | |
115 case SkXfermode::kISA_Coeff: | |
116 *needSrcValue = true; | |
117 break; | |
118 default: | |
119 *needSrcValue = false; | |
120 break; | |
121 } | |
122 } else { | |
123 *needSrcValue = true; | |
124 } | |
125 if (SkXfermode::kZero_Coeff == dstCoeff) { | |
126 switch (srcCoeff) { | |
127 // these all read the dst | |
128 case SkXfermode::kDC_Coeff: | |
129 case SkXfermode::kIDC_Coeff: | |
130 case SkXfermode::kDA_Coeff: | |
131 case SkXfermode::kIDA_Coeff: | |
132 *needDstValue = true; | |
133 break; | |
134 default: | |
135 *needDstValue = false; | |
136 break; | |
137 } | |
138 } else { | |
139 *needDstValue = true; | |
140 } | |
141 } | |
142 | |
143 /** | |
144 * Create a blend_coeff * value string to be used in shader code. Sets empty | |
145 * string if result is trivially zero. | |
146 */ | |
147 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, | |
148 const char* src, const char* dst, | |
149 const char* value) { | |
150 switch (coeff) { | |
151 case SkXfermode::kZero_Coeff: /** 0 */ | |
152 *str = ""; | |
153 break; | |
154 case SkXfermode::kOne_Coeff: /** 1 */ | |
155 *str = value; | |
156 break; | |
157 case SkXfermode::kSC_Coeff: | |
158 str->printf("(%s * %s)", src, value); | |
159 break; | |
160 case SkXfermode::kISC_Coeff: | |
161 str->printf("((vec4(1) - %s) * %s)", src, value); | |
162 break; | |
163 case SkXfermode::kDC_Coeff: | |
164 str->printf("(%s * %s)", dst, value); | |
165 break; | |
166 case SkXfermode::kIDC_Coeff: | |
167 str->printf("((vec4(1) - %s) * %s)", dst, value); | |
168 break; | |
169 case SkXfermode::kSA_Coeff: /** src alpha */ | |
170 str->printf("(%s.a * %s)", src, value); | |
171 break; | |
172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | |
173 str->printf("((1.0 - %s.a) * %s)", src, value); | |
174 break; | |
175 case SkXfermode::kDA_Coeff: /** dst alpha */ | |
176 str->printf("(%s.a * %s)", dst, value); | |
177 break; | |
178 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ | |
179 str->printf("((1.0 - %s.a) * %s)", dst, value); | |
180 break; | |
181 default: | |
182 GrCrash("Unexpected xfer coeff."); | |
183 break; | |
184 } | |
185 } | |
186 /** | |
187 * Adds a line to the fragment shader code which modifies the color by | |
188 * the specified color filter. | |
189 */ | |
190 void add_color_filter(GrGLShaderBuilder* builder, | |
191 const char * outputVar, | |
192 SkXfermode::Coeff uniformCoeff, | |
193 SkXfermode::Coeff colorCoeff, | |
194 const char* filterColor, | |
195 const char* inColor) { | |
196 SkString colorStr, constStr; | |
197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | |
198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | |
199 GrGLSLExpr<4> sum; | |
200 if (colorStr.isEmpty() && constStr.isEmpty()) { | |
201 sum = GrGLSLExpr<4>(0); | |
202 } else if (colorStr.isEmpty()) { | |
203 sum = constStr; | |
204 } else if (constStr.isEmpty()) { | |
205 sum = colorStr; | |
206 } else { | |
207 sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr); | |
208 } | |
209 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | |
210 } | |
211 } | |
212 | |
213 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, | 101 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
214 const GrEffectStage* colorStages[], | 102 const GrEffectStage* colorStages[], |
215 const GrEffectStage* coverageStages[]) { | 103 const GrEffectStage* coverageStages[]) { |
216 SkASSERT(0 == fProgramID); | 104 SkASSERT(0 == fProgramID); |
217 | 105 |
218 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 106 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
219 | 107 |
220 // incoming color to current stage being processed. | 108 // incoming color to current stage being processed. |
221 GrGLSLExpr<4> inColor = builder->getInputColor(); | 109 GrGLSLExpr<4> inColor = builder->getInputColor(); |
222 | 110 |
223 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | |
224 SkXfermode::Coeff colorCoeff; | |
225 SkXfermode::Coeff filterColorCoeff; | |
226 SkAssertResult( | |
227 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | |
228 &filterColorCoeff, | |
229 &colorCoeff)); | |
230 bool needColor, needFilterColor; | |
231 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | |
232 | |
233 fColorEffects.reset( | 111 fColorEffects.reset( |
234 builder->createAndEmitEffects(colorStages, | 112 builder->createAndEmitEffects(colorStages, |
235 fDesc.effectKeys(), | 113 fDesc.effectKeys(), |
236 needColor ? fDesc.numColorEffects() : 0, | 114 fDesc.numColorEffects(), |
237 &inColor)); | 115 &inColor)); |
238 | 116 |
239 // Insert the color filter. This will soon be replaced by a color effect. | |
240 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | |
241 const char* colorFilterColorUniName = NULL; | |
242 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, | |
243 kVec4f_GrSLType, "
FilterColor", | |
244 &colorFilterColorU
niName); | |
245 | |
246 builder->fsCodeAppend("\tvec4 filteredColor;\n"); | |
247 add_color_filter(builder, "filteredColor", filterColorCoeff, | |
248 colorCoeff, colorFilterColorUniName, inColor.c_str()); | |
249 inColor = "filteredColor"; | |
250 } | |
251 | |
252 /////////////////////////////////////////////////////////////////////////// | 117 /////////////////////////////////////////////////////////////////////////// |
253 // compute the partial coverage | 118 // compute the partial coverage |
254 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); | 119 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); |
255 | 120 |
256 fCoverageEffects.reset( | 121 fCoverageEffects.reset( |
257 builder->createAndEmitEffects(coverageStages, | 122 builder->createAndEmitEffects(coverageStages, |
258 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), | 123 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
259 fDesc.numCoverageEffects(), | 124 fDesc.numCoverageEffects(), |
260 &inCoverage)); | 125 &inCoverage)); |
261 | 126 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 coverage = drawState.getCoverage(); | 212 coverage = drawState.getCoverage(); |
348 } else { | 213 } else { |
349 color = drawState.getColor(); | 214 color = drawState.getColor(); |
350 coverage = drawState.getCoverage(); | 215 coverage = drawState.getCoverage(); |
351 } | 216 } |
352 | 217 |
353 this->setColor(drawState, color, sharedState); | 218 this->setColor(drawState, color, sharedState); |
354 this->setCoverage(drawState, coverage, sharedState); | 219 this->setCoverage(drawState, coverage, sharedState); |
355 this->setMatrixAndRenderTargetHeight(drawState); | 220 this->setMatrixAndRenderTargetHeight(drawState); |
356 | 221 |
357 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary | |
358 if (fUniformHandles.fColorFilterUni.isValid() && | |
359 fColorFilterColor != drawState.getColorFilterColor()) { | |
360 GrGLfloat c[4]; | |
361 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); | |
362 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); | |
363 fColorFilterColor = drawState.getColorFilterColor(); | |
364 } | |
365 | |
366 if (NULL != dstCopy) { | 222 if (NULL != dstCopy) { |
367 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { | 223 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { |
368 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, | 224 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, |
369 static_cast<GrGLfloat>(dstCopy->offset().fX), | 225 static_cast<GrGLfloat>(dstCopy->offset().fX), |
370 static_cast<GrGLfloat>(dstCopy->offset().fY)); | 226 static_cast<GrGLfloat>(dstCopy->offset().fY)); |
371 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, | 227 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, |
372 1.f / dstCopy->texture()->width(), | 228 1.f / dstCopy->texture()->width(), |
373 1.f / dstCopy->texture()->height()); | 229 1.f / dstCopy->texture()->height()); |
374 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; | 230 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; |
375 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. | 231 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. |
(...skipping 28 matching lines...) Expand all Loading... |
404 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { | 260 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { |
405 // OpenGL ES only supports the float varieties of glVertexAt
trib | 261 // OpenGL ES only supports the float varieties of glVertexAt
trib |
406 GrGLfloat c[4]; | 262 GrGLfloat c[4]; |
407 GrColorToRGBAFloat(color, c); | 263 GrColorToRGBAFloat(color, c); |
408 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); | 264 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); |
409 sharedState->fConstAttribColor = color; | 265 sharedState->fConstAttribColor = color; |
410 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; | 266 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; |
411 } | 267 } |
412 break; | 268 break; |
413 case GrGLProgramDesc::kUniform_ColorInput: | 269 case GrGLProgramDesc::kUniform_ColorInput: |
414 if (fColor != color) { | 270 if (fColor != color && fUniformHandles.fColorUni.isValid()) { |
415 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform | 271 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform |
416 GrGLfloat c[4]; | 272 GrGLfloat c[4]; |
417 GrColorToRGBAFloat(color, c); | 273 GrColorToRGBAFloat(color, c); |
418 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); | 274 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); |
419 fColor = color; | 275 fColor = color; |
420 } | 276 } |
421 sharedState->fConstAttribColorIndex = -1; | 277 sharedState->fConstAttribColorIndex = -1; |
422 break; | 278 break; |
423 case GrGLProgramDesc::kSolidWhite_ColorInput: | 279 case GrGLProgramDesc::kSolidWhite_ColorInput: |
424 case GrGLProgramDesc::kTransBlack_ColorInput: | 280 case GrGLProgramDesc::kTransBlack_ColorInput: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 348 |
493 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 349 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
494 fMatrixState.fRenderTargetSize = size; | 350 fMatrixState.fRenderTargetSize = size; |
495 fMatrixState.fRenderTargetOrigin = rt->origin(); | 351 fMatrixState.fRenderTargetOrigin = rt->origin(); |
496 | 352 |
497 GrGLfloat viewMatrix[3 * 3]; | 353 GrGLfloat viewMatrix[3 * 3]; |
498 fMatrixState.getGLMatrix<3>(viewMatrix); | 354 fMatrixState.getGLMatrix<3>(viewMatrix); |
499 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 355 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
500 } | 356 } |
501 } | 357 } |
OLD | NEW |